【问题标题】:Weak self is getting nil inside the block but i want to use self object inside the block弱自我在块内变为零,但我想在块内使用自我对象
【发布时间】:2016-11-25 21:38:46
【问题描述】:

我编写了一个示例代码来建立服务器连接。请在下面找到我写的代码。

__weak typeof(self) weakSelf = self;
self.dataTask = [defaultSession dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
{
    weakSelf.dataTask = nil;
    NSInteger extractionResponseCode = [((NSHTTPURLResponse *)response) statusCode];
    if (!error && data.length > 0 && extractionResponseCode == 200)
    {
        [weakSelf handleResponse:data];
    }
    else
    {
        [weakSelf handleError:error];
    }
}];

收到回复后,我必须根据回复致电handleResponse:handleError:

我采取了weakSelf 来避免ARC 中的保留循环问题。

我的问题是在块内,weakSelf 越来越为零,因此既没有调用 handleResponse: 也没有调用 handleError: 方法。

您能帮我解决这个问题吗?

提前致谢。

【问题讨论】:

    标签: ios objective-c automatic-ref-counting objective-c-blocks


    【解决方案1】:

    答案是获取强参考。无论如何,您都没有保留周期,除非self 引用了完成块。无论如何,当块返回时,强引用将被释放,如果你碰巧有一个,这将打破循环。

    【讨论】:

      【解决方案2】:

      这个想法是下载数据不应该让您的对象保持活动状态。如果您的对象在下载运行时消失了(例如,如果用户从导致下载的屏幕切换到另一个屏幕),那么您应该忽略结果并将其丢弃,或者将其存储到文件中,但您应该允许 self 变为 nil。

      这与引用循环无关:如果你不使用weakSelf,self最终消失,但你不应该让它存活的时间超过需要的时间。最坏的情况是,您可能会向用户显示有关屏幕早已消失的错误警报。失败的 URL 请求可能需要 60 秒才能失败,因此用户可能已经做了完全不同的事情。

      使用weakSelf的正确方法是在你的回调函数中将它赋给一个新的变量strongSelf,然后检查它是否为nil。直接使用weakSelf 是不好的,因为它随时可能变为nil。

      【讨论】:

        【解决方案3】:

        我真的很想知道,为什么人们认为每次捕获它时都需要削弱自我。

        正如术语保留循环所说,你只能有一个,如果你有一个对象的引用,该对象引用了持有第一个引用的对象(直接或通过许多其他引用) .

        因此,如果块上下文引用self,那么当且仅当块被self 引用时,您就有一个引用循环。 (顺便说一句:这适用于每个(强)引用。在 Objective-C 中,self 没有什么特别之处。)你没有那个。 在您的情况下,没有理由削弱 self

        但是,有些人想弱化它,在这种情况下使selfnil。这就是意图。在某些情况下,这可能是一个优势:只需考虑一个模型对象在为其下载数据时就消失了。没有理由让它活着。

        如果你不想这样,就不要弱化self就是这么简单。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-06-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多