Ios 可选闭包总是转义吗?我们应该在上面使用[弱自我]还是[无主自我]?
在UICollectionView中提供以下函数签名 在Internet上有一些选项,可选的闭包总是在转义。但是,我真的不确定这是真的,或者这仍然是有争议的 对于上述情况,我们是否需要在第一个街区中使用[弱自我],或[无主自我],以及第二个黑色Ios 可选闭包总是转义吗?我们应该在上面使用[弱自我]还是[无主自我]?,ios,swift,Ios,Swift,在UICollectionView中提供以下函数签名 在Internet上有一些选项,可选的闭包总是在转义。但是,我真的不确定这是真的,或者这仍然是有争议的 对于上述情况,我们是否需要在第一个街区中使用[弱自我],或[无主自我],以及第二个黑色 func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) { collectionView!.per
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
collectionView!.performBatchUpdates({ () -> Void in
for operation: BlockOperation in self.blockOperations {
operation.start()
}
}, completion: { (finished) -> Void in
self.blockOperations.removeAll(keepingCapacity: false)
self.collectionView.reloadData()
})
}
根据编译器的观点,对于这样的事情,唯一重要的是一个可选的闭包参数总是隐式地@escaping。通过编写一个接受可选闭包的函数并将其标记为@escaping,您可以自己进行测试。编译器将通知您它已在转义 至于你是否应该把自己看作是弱者还是无主者,那要看情况而定。首先,我不想把self看作是无主的,除非你想让你的程序崩溃,如果你对self的一生错了,你可能会这样做。我宁愿我的程序崩溃,也不愿默默地做错事 但这就使得是否捕获变得很弱。我的观点是肯定的,如果你对获取一个强引用有任何怀疑的话,那么就创建一个引用循环,阻止它正确地去初始化。但我不会说永远或者永远不做什么。如果您能够对对象的生命周期进行推理,从而知道在对象正常去初始化之前将运行并处理闭包,那么只需捕获作为强引用即可。如果您有意为了闭包而延长对象的生命,并且您知道闭包将被执行和处理,那么也可以通过强引用进行捕获 还有一种情况是,你知道尽管隐式地@escaping,但它实际上并没有逃逸。通常,这是针对在代码库中定义的函数的,因此您可以查看实现,但实际上,任何时候,闭包只是一个自定义点,用于在调用的函数返回之前必须完成的工作,您都可以推断它实际上没有转义。对于完成处理程序,情况并非如此,但对于其他事情,情况可能会如此
这是我的意见。我喜欢认为这是一个明智的选择,但其他人可能不同意。因为我们没有访问collectionView.performBatch update的权限,我们永远无法知道实现者是以转义方式还是非转义方式执行这两个块。即使他以不逃逸的方式实施这些区块,也不能保证他将来不会以逃逸的方式实施。这是否意味着出于预防目的,在这种情况下我们将使用[弱自我]?是的。当它怀疑时,[软弱的自我]才是出路。在performBatchUpdate中,我们可以做出一些合理的推断,即闭包实际上会逃逸。确实,完成处理程序实际上会转义。。。这就是完成处理程序的工作方式。但这也告诉你,它将异步完成工作,因此更新闭包几乎肯定也会逃逸。虽然很明显,如果self引用的内容将一直存在到应用程序终止,那么捕获对self的强引用并不是问题。例如,您的应用程序委托,或者如果您将Napplication/UIApplication子类化,甚至可能是应用程序本身。此外,单身人士将在该计划的整个生命周期中继续生活。在这种情况下,没有必要[软弱的自我]。。。不过,这并没有什么坏处,只是拆开可选包装的成本很小。是的。我同意,在有疑问的时候,安全总比后悔好。使用安全方法[弱自我]来防止内存泄漏,造成的危害比拆封成本小。
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
collectionView!.performBatchUpdates({ () -> Void in
for operation: BlockOperation in self.blockOperations {
operation.start()
}
}, completion: { (finished) -> Void in
self.blockOperations.removeAll(keepingCapacity: false)
self.collectionView.reloadData()
})
}