Ios 弱self在块内得到nil,但我想在块内使用self对象
我已经编写了一个用于建立服务器连接的示例代码。请找到我在下面写的代码Ios 弱self在块内得到nil,但我想在块内使用self对象,ios,objective-c,automatic-ref-counting,objective-c-blocks,Ios,Objective C,Automatic Ref Counting,Objective C Blocks,我已经编写了一个用于建立服务器连接的示例代码。请找到我在下面写的代码 __weak typeof(self) weakSelf = self; self.dataTask = [defaultSession dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { weakSelf.dataTask = nil; NSIntege
__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:
为了避免ARC中的保留周期问题,我采取了weakSelf
我这里的问题是在块内部,weakSelf变为nil,因此既不调用handleResponse:
也不调用handleError:
方法
您能帮我解决这个问题吗?
提前感谢。答案是获取一个有力的参考。除非
self
引用了完成块,否则您没有保留循环。当块返回时,强引用将被释放,如果你恰好有一个强引用,这将打破循环。这个想法是下载数据不应该让你的对象保持活动状态。如果您的对象在下载运行时消失(例如,如果用户从导致下载的屏幕切换到另一个屏幕),那么您应该忽略结果并将其丢弃,或者将其存储到文件中,但您应该允许self变为零
这与参考周期无关:如果你不使用weakSelf,self最终会消失,但你不应该让它活得比需要的时间更长。最糟糕的情况是,您可能会向用户显示一个关于已消失很久的屏幕的错误警报。失败的URL请求可能需要60秒才能失败,因此用户可能已经做了完全不同的事情
使用weakSelf的正确方法是将其分配给回调中的新变量strongSelf,然后检查它是否为nil。直接使用weakSelf是不好的,因为它可以在任何时候变为零 我真的很想知道,为什么人们认为每次你捕捉到自己的时候,你都需要削弱自己 正如术语retain cycle所说,如果对一个对象的引用引用了包含第一个引用的对象(直接引用或通过许多其他引用),则只能有一个引用 因此,如果块上下文指的是
self
,则只有当且仅当块由self
引用时,才有一个引用循环。(顺便说一句:这适用于所有(强)引用。在Objective-C中,self
,没有什么特别之处。)你没有这个。在您的情况下,防止保留周期不是削弱self
的理由
然而,有些人想削弱它,在这种情况下使自我nil
。这就是目的。在某些情况下,这可能是一个优势:只需想象一个模型对象在为其下载数据时消失了。没有理由让它活着
如果你不想这样,就不要削弱自己。就这么简单