我是否需要在块内的strongSelf = weakSelf赋值中检查nil?

时间:2015-08-16 23:46:21

标签: ios objective-c objective-c-blocks retain-cycle

例如,我正在使用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) {

这就是我问的原因。从这个链接上的#3点开始(http://www.apeth.com/iOSBook/ch12.html#EXstrongWeakDance)它说“nil测试是因为,在多线程的情况下,我们对自我的弱引用可能在上一步之前从我们之下消失了;它会然后是零,因为它是一个ARC弱引用,在这种情况下,没有必要继续。“

需要检查吗?我想第一次在块中使用了weakSelf的引用时,它会在表达式的持续时间内保留吗?

3 个答案:

答案 0 :(得分:1)

我想你的意思是:

if (!strongSelf.endReached) {

如果self为nil,这将评估为YES,这可能不是你想要的。

发生你的代码做了正确的事情(什么都不做)因为两个子句只使用self来调用方法,然后什么都不会发生。最终结果与使用nil-check相同,但执行路径错误。如果有人添加了不使用self的代码,这可能会在将来产生影响。

答案 1 :(得分:0)

对于您发布的代码,不需要检查nil

这行代码:

if (!strongSelf.endReached) {

如果strongSelf为零,则eval为false。进一步阅读:Sending a message to nil?

然后这行代码将执行:

[strongSelf.tableView.infiniteScrollingView stopAnimating];

如果strongSelf为零,该行将完全不执行任何操作(甚至不会出现错误)。

然而,一些开发人员认为无论如何都要检查nil是最佳做法,因为有人后来添加了代码并且它确实关心nil。所以你应该考虑做:

MyViewController *strongSelf = weakSelf;
if (!strongSelf) {
  return;
}

... the rest of your code ...

答案 2 :(得分:0)

您的来源指的是weakSelf可能已被解除分配,nil在执行该块甚至可能开始之前的事实;因此,在strongSelf获得强有力的参考并保留它之前。 strongSelf用于确保在块执行期间weakSelf引用的对象不是nil&#39;

在ARC中没有概念#34;使用&#34;在处理retain变量时,__weak变量需要__weak变量,{em>明确选择退出此变量。

话虽如此,在这种情况下严格说来检查是不必要的,因为到nil的消息总是无操作。如果您打算将strongSelf插入到数组中,或者如果在消息之间取消分配将使您的程序处于无效状态,那么这将是另一回事。

总而言之,每当您需要保证__weak变量不会nil一段时间后,请使用__strong,并在使用之前进行检查它不是nil