简体   繁体   English

我是否需要在代码块中检查strongSelf = weakSelf分配是否为零?

[英]Do I need to check for nil on my strongSelf = weakSelf assignment inside a block?

For example, I'm using SVInfiniteScrolling ( https://github.com/alexanderedge/SVInfiniteScrolling ). 例如,我正在使用SVInfiniteScrolling( https://github.com/alexanderedge/SVInfiniteScrolling )。

I have some code that looks like this... 我有一些看起来像这样的代码...

- (void)initializeInfiniteScrollingForTableView {
    __weak MyViewController *weakSelf = self;

    [self.tableView addInfiniteScrollingWithActionHandler:^{
        MyViewController *strongSelf = weakSelf;
        if (!strongSelf.endReached) {
            [strongSelf fetchData];
        }
        else {
            [strongSelf.tableView.infiniteScrollingView stopAnimating];
        }
    }];
}

What I'm wondering is... do I need to check strongSelf for nil before using like this... 我想知道的是...在像这样使用之前,我是否需要检查strongSelf是否为零...

...
[self.tableView addInfiniteScrollingWithActionHandler:^{
    MyViewController *strongSelf = weakSelf;
    if (strongSelf) { // <== ** Is this needed? **
        if (!strongSelf.endReached) {

Here is why I ask. 这就是为什么我问。 From point #3 on this link ( http://www.apeth.com/iOSBook/ch12.html#EXstrongWeakDance ) it says "The nil test is because, in a multithreaded situation, our weak reference to self may have vanished out from under us before the previous step; it would then be nil, because it's an ARC weak reference, and in that case there would be no point continuing." 从此链接上的第3点( http://www.apeth.com/iOSBook/ch12.html#EXstrongWeakDance )来看, “零测试是因为在多线程情况下,我们对自我的弱引用可能已从在我们之前没有进行下一步;那么它将为零,因为它是ARC的弱参考,在那种情况下将毫无意义。

Is this check needed? 需要这张支票吗? I thought the first time you used the reference to weakSelf within the block, it is retained for the duration of the expression? 我以为您是第一次在块中使用对weakSelf的引用时,该表达式会在表达式持续时间内保留吗?

I think in your line: 我认为在您看来:

if (!strongSelf.endReached) {

this will evaluate to YES if self is nil, which is not probably not you intend. 如果self为零,则结果将为YES,这可能不是您想要的。

It happens that your code does the correct thing (do nothing) because both clauses only use self to call methods and then nothing will happen. 碰巧您的代码做了正确的事情(什么也不做),因为两个子句都只使用self来调用方法,然后什么也不会发生。 The end result is the same as if you had the nil-check but the execution path is wrong. 最终结果与进行nil-check相同,但是执行路径错误。 This might have consequences in the future if someone adds code that doesn't use self. 如果有人添加了不使用self的代码,将来可能会产生后果。

For the code you posted, checking for nil is unnecessary. 对于您发布的代码,无需检查nil

This line of code: 这行代码:

if (!strongSelf.endReached) {

Will eval to false if strongSelf is nil. 如果strongSelf为nil,则将评估为false。 Further reading: Sending a message to nil? 进一步阅读: 向nil发送消息?

And then this line of code will execute: 然后这行代码将执行:

[strongSelf.tableView.infiniteScrollingView stopAnimating];

That line will just do nothing at all (not even an error) if strongSelf is nil. 如果strongSelf为零,那么该行将根本不执行任何操作(甚至不会出错)。

However, some developers consider it a best practice to check for nil anyway, incase somebody later adds the code and it does care about nil. 但是,一些开发人员认为最好还是检查nil,以防万一有人后来添加了代码并且确实关心nil。 So you should consider doing: 因此,您应该考虑这样做:

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

... the rest of your code ...

Your source is referring to the fact that weakSelf may have been deallocated and nil 'd before execution of the block could even begin; 您的消息来源是指这样的事实,即weakSelf在执行该块之前, weakSelf可能已被释放并nil and therefore, before strongSelf acquired a strong reference and retained it. 因此,在strongSelf获得强大的参考并保留之前。 The strongSelf is to ensure that the object referenced by weakSelf is not nil 'd during the block's execution. 所述strongSelf是确保通过引用的对象weakSelf不是nil块的执行期间 “d。

There is no notion in ARC of "using" a variable making it necessary to retain it when dealing with __weak variables -- __weak is explicitly opting out of this. ARC中没有“使用”变量的概念,因此在处理__weak变量时有必要retain__weak __weak 明确选择退出。

With that said, the check isn't strictly speaking necessary in this case, since messages to nil are always no-ops. 话虽这么说,在这种情况下检查并不是严格意义上的,因为发送到nil消息始终是无操作的。 If you intended to insert strongSelf into an array, or if it being deallocated between messages would put your program into an invalid state, it would be another matter. 如果您打算将strongSelf插入一个数组中,或者如果在消息之间取消分配它会使您的程序处于无效状态,那将是另一回事。

To conclude, whenever you need to guarentee that a __weak variable will not be nil 'd for a period of time, use __strong , and check before using it that it is not nil . 总而言之,每当需要确保__weak变量在一段时间内不会nil时,请使用__strong ,并在使用前检查它是否为nil

暂无
暂无

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

相关问题 当weakSelf在块中为零时,应该添加strongSelf - when weakSelf will be nil in block ,when should add strongSelf 我需要强壮自我来保持自我活力,强壮自我真的有效吗? - Do I need a strongSelf in block to keep self alive and does the strongSelf really work? 在从 UIViewController 调用的非保留完成中引用 self 时,weakSelf/strongSelf 舞蹈真的有必要吗? - Is the weakSelf/strongSelf dance really necessary when referencing self inside a non-retained completion called from a UIViewController? 弱自我(好),强自我(坏)和阻止(丑陋) - weakSelf (the good), strongSelf (the bad) and blocks (the ugly) iOS - 我应该在这个区块中调用“weakSelf”吗? - iOS - Should I be calling “weakSelf” in this block? 我什么时候应该在块中使用弱势,为什么砌体中没有保留周期? - When should I use weakself in a block, and why there is no retain cycle in Masonry? 在ARC中,dealloc方法调用包含对self的弱引用的method / block,从而导致weakSelf = nil - In ARC, dealloc method calls method/block that contains weak reference to self result in weakSelf = nil 在 ReactiveObjc 中使用 @strongify(self) 之前,我应该检查弱自我的存在吗? - Should I check the existence of weakself before use @strongify(self) in ReactiveObjc? 如果未在块内检测到nil? - If not detecting nil inside block? 我是否需要DispatchQueue.main.async中的autoreleasepool块 - Do I need an autoreleasepool block inside a DispatchQueue.main.async
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM