在尝试同步函数时,许多帖子似乎都建议不要使用通知,但是还有其他帖子提醒不要关闭回调,因为可能会无意中保留对象并导致内存问题。
假设自定义视图控制器内部是一个函数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
。
选项1似乎是可取的,因为人们提醒NSNotification
的所有原因(例如,编译器检查,可追溯性),但不使用回调会产生潜在的问题,CustomViewController
被不必要地保留,因此可能会造成内存问题?
如果是这样,是使用回调来降低风险的正确方法,而不是使用闭包?换句话说,在CustomViewController
内定义一个带有与getServerData
回调匹配的签名的函数,并将指向此函数的指针传递给getServerData
?
答案 0 :(得分:0)
我总是选择选项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)
}
}
}
答案 1 :(得分:0)
在这种情况下,我代表关闭。为了避免不必要的保留,您只需要确保关闭具有正确的capture list定义。