ios - 在网络调用的通知与回调关闭之间进行选择时是否担心内存?

标签 ios swift uiviewcontroller delegates nsnotificationcenter

许多帖子似乎建议在尝试同步函数时不要使用通知,但也有其他帖子警告不要使用闭包回调,因为可能会无意中保留对象并导致内存问题。

假设在自定义 View Controller 中有一个函数 foo,它使用 Bar 类从服务器获取数据。

class CustomViewController : UIViewController {

    function foo() {
       // Do other stuff
       // Use Bar to get data from server
       Bar.getServerData()
     }

}

选项 1:定义 getServerData 以接受回调。将回调定义为 CustomViewController 中的闭包。

选项 2:使用 NSNotifications 而不是回调。在 getServerData 中,当服务器返回数据时发送一个 NSNotification,并确保 CustomViewController 已注册通知。

由于人们警告不要使用 NSNotification 的所有原因(例如,编译器检查、可追溯性),选项 1 似乎是可取的,但不使用回调会导致 CustomViewController 的潜在问题> 被不必要地保留,因此可能会产生内存问题?

如果是这样,使用回调而不是闭包来降低风险的正确方法是什么?换句话说,在 CustomViewController 中定义一个函数,其签名与 getServerData 回调匹配,并将指向此函数的指针传递给 getServerData?

最佳答案

我总是选择选项 1 你只需要记住使用 [weak self] 或任何你需要“弱化”以避免内存问题的东西.

现实世界的例子:

filterRepository.getFiltersForType(filterType) { [weak self] (categories)  in
    guard let strongSelf = self, categories = categories else { return }
    strongSelf.dataSource           = categories
    strongSelf.filteredDataSource   = strongSelf.dataSource
    strongSelf.tableView?.reloadData()
}

所以在这个例子中你可以看到我将对 self 的引用传递给完成闭包,但是作为 weak 引用。然后我检查对象是否仍然存在 - 如果它还没有被释放,使用 guard 语句并展开 weak 值。

带有完成闭包的网络调用的定义:

class func getFiltersForType(type: FilterType, callback: ([FilterCategory]?) -> ()) {
    connection.getFiltersCategories(type.id).response { (json, error) in
        if let data = json {
            callback(data.arrayValue.map { FilterCategory(attributes: $0) } )
        } else {
            callback(nil)
        }
    }
}

关于ios - 在网络调用的通知与回调关闭之间进行选择时是否担心内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36831406/

相关文章:

ios - 动态类型检查混淆 Swift

ios - 屏幕上未显示的 VC 的屏幕截图

swift - 推/退时隐藏/显示标签栏。 swift

objective-c - 如何在 subview 中使用addChildViewController

ios - 执行 segue 时哪个对象是发送者?

iphone - MPMoviePlayerController 和来电

ios - 从 reverseGeocodeLocation 仅返回英文地址

ios - 使用现有 key 对加密/解密文本

ios - dateFromString 对某些值返回 nil

ios - 如果 Realm 对象为空,我如何返回或创建一个 Realm 对象?