【发布时间】:2015-08-16 23:46:21
【问题描述】:
例如,我正在使用 SVInfiniteScrolling (https://github.com/alexanderedge/SVInfiniteScrolling)。
我有一些看起来像这样的代码...
- (void)initializeInfiniteScrollingForTableView {
__weak MyViewController *weakSelf = self;
[self.tableView addInfiniteScrollingWithActionHandler:^{
MyViewController *strongSelf = weakSelf;
if (!strongSelf.endReached) {
[strongSelf fetchData];
}
else {
[strongSelf.tableView.infiniteScrollingView stopAnimating];
}
}];
}
我想知道的是......我需要在这样使用之前检查 strongSelf 是否为零......
...
[self.tableView addInfiniteScrollingWithActionHandler:^{
MyViewController *strongSelf = weakSelf;
if (strongSelf) { // <== ** Is this needed? **
if (!strongSelf.endReached) {
这就是我问的原因。从这个链接 (http://www.apeth.com/iOSBook/ch12.html#EXstrongWeakDance) 上的第 3 点开始,它说 “nil 测试是因为,在多线程情况下,我们对 self 的弱引用可能在上一步之前已经从我们下面消失了;然后它将是无,因为它是一个 ARC 弱引用,在这种情况下,继续没有意义。”
需要这个检查吗?我以为你第一次在块中使用了对 weakSelf 的引用,它会在表达式的持续时间内保留?
【问题讨论】:
-
@zaph 嗯。我正在努力思考这个问题。我对这个块没有强烈的参考吗?如果您查看包含 UIScrollView 的函数 addInfiniteScrollingWithActionHandler 的类别,它将块保存在视图中,然后将子视图添加到 UIScrollView(在本例中为我的 tableview)。这意味着我的 tableview 对块有很强的引用。我需要通过上面的弱强舞蹈来打破它。这不正确吗?
-
@zaph 我希望你能帮助我理解这个过程。这个问题总是让我陷入困境。所以这个属性块就在这里(github.com/alexanderedge/SVInfiniteScrolling/blob/master/…),它在这里设置(github.com/alexanderedge/SVInfiniteScrolling/blob/master/…)。只要它存在,我的 self.tableView 就持有这个块,对吗?而且这个街区会强烈地引用我(没有舞蹈),对吧?我错过了什么?
-
@zaph 所以我什至不需要将弱重新分配给强,因为这不是多线程情况,并且块在主线程上运行对吗?只是 weakSelf 本身会阻止这里的保留循环,我很好,对吗?
-
@zaph 我不同意这个保留周期。此链接上的第二个代码块有一个很好的例子。 blackpixel.com/writing/2014/03/capturing-myself.html (来自链接:“如果块包含在另一个对象中,而该对象自身保持强引用”)。当 self 没有抓住块时,infiniteScrolling 的东西抓住了块,而 self 抓住了 infiniteScrolling 的东西。如链接所示,编译器不会注意到并警告您,但它仍会创建一个保留循环。
-
@zaph 接口文件中有指向self.tableView的强指针。它坚持住块。就像在最后一个链接中一样,没有指向块的指针,但是有一个指向这个 tableView 的指针,它保存了块。
标签: ios objective-c objective-c-blocks retain-cycle