简体   繁体   English

弱自我在块内部变为nil但我想在块内使用self对象

[英]Weak self is getting nil inside the block but i want to use self object inside the block

I have written a sample code to make a server connection. 我编写了一个示例代码来建立服务器连接。 Please find the code that I have written below. 请找到我在下面写的代码。

__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];
    }
}];

After getting the response I have to call either handleResponse: or handleError: based on the response. 获得响应后,我必须根据响应调用handleResponse:handleError: .

I have taken weakSelf to avoid retain cycle problem in ARC. 我已经采用weakSelf来避免ARC中的保留周期问题。

My problem here is inside the block weakSelf is getting as nil so neither handleResponse: nor handleError: methods are called. 我的问题在于块weakSelf内部为nil所以既没有handleResponse:也没有handleError:方法被调用。

Could you please help me how can I resolve this issue.? 你能帮我解决一下这个问题吗?

Thanks in advance. 提前致谢。

The answer is to capture a strong reference. 答案是捕获一个强有力的参考。 You don't have a retain cycle anyway, unless self has a reference to the completion block. 您无论如何都没有保留周期,除非self具有对完成块的引用。 And the strong reference will be released anyway, when the block returns, which will break the cycle if you do happen to have one. 无论如何,当块返回时,强引用将被释放,如果你碰巧有一个,它将打破周期。

I really wonder, why people think that you need to weakify self every time you capture it. 我真的很想知道,为什么人们认为每次捕获它都需要削弱自我。

As the term retain cycle says, you can only have one, if you have a reference to an object that refers to the object holding the first reference (directly or via a number of other references). 正如术语“ 保留周期 ”所述,如果您引用了一个引用第一个引用的对象的对象(直接或通过许多其他引用),则只能有一个引用。

So if the block context refers to self , you have a reference cycle, if and only if the block is referred by self . 因此,如果块上下文引用self ,则当有且仅当块由self引用时,才有引用周期。 (BTW: This applies to every (strong) reference. There is nothing special about self in Objective-C, nowhere.) You do not have that. (顺便说一句:这适用于每一个(强)参考。在Objective-C中没有任何关于self特别之处。)你没有那个。 Preventing from retain cycles is no reason to weakify self in your case. 在你的情况下,防止保留周期是没有理由削弱self

However, some want to weakify it, to make self nil in such a case. 然而,有些人想要削弱它,在这种情况下使self nil This is the intention. 这是意图。 This can be an advantage under some circumstances: Simply think of a model object that is gone while downloading data for it. 在某些情况下,这可能是一个优势:只需考虑在为其下载数据时已经消失的模型对象。 There is no reason to keep it alive. 没有理由让它保持活力。

If you do not want that, simply do not weakify self . 如果你不想那样,就不要削弱self It is that simple. 这么简单。

The idea is that downloading data shouldn't keep your object alive. 这个想法是下载数据不应该让你的对象保持活力。 If your object goes away while the download is running (for example if the user switches from the screen causing the download to aother screen) then you should just ignore the result and throw it away, or maybe store it to a file, but you should allow self to become nil. 如果您的对象在下载运行时消失(例如,如果用户从屏幕切换导致下载到另一个屏幕),那么您应该忽略结果并将其丢弃,或者将其存储到文件中,但是您应该让自己变成零。

This has nothing to do with a reference cycle: self will go away eventually if you don't use weakSelf, but you shouldn't keep it alive longer than needed. 这与参考周期无关:如果你不使用weakSelf,self最终消失,但是你不应该让它比所需的更长时间。 Worst case, you might show an error alert to the user about a screen that has long gone. 最糟糕的情况是,您可能会向用户显示一条错误警告,该警告已经消失了。 A failing URL request might take 60 seconds to fail, so the user might do something completely different already. 失败的URL请求可能需要60秒才能失败,因此用户可能已经做了一些完全不同的事情。

The correct way to use weakSelf is to assign it to a new variable strongSelf in your callback, then check that it is not nil. 使用weakSelf的正确方法是将其分配给回调中的新变量strongSelf,然后检查它是否为nil。 Using weakSelf directly is bad because it can become nil at any time. 直接使用weakSelf是不好的,因为它可以随时变为零。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM