Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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).

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...

...
[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."

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?

like image 317
chris P Avatar asked Oct 23 '25 02:10

chris P


2 Answers

For the code you posted, checking for nil is unnecessary.

This line of code:

if (!strongSelf.endReached) {

Will eval to false if strongSelf is nil. Further reading: Sending a message to 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.

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. So you should consider doing:

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

... the rest of your code ...
like image 106
Abhi Beckert Avatar answered Oct 26 '25 07:10

Abhi Beckert


I think in your line:

if (!strongSelf.endReached) {

this will evaluate to YES if self is nil, which is not probably not you intend.

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. The end result is the same as if you had the nil-check but the execution path is wrong. This might have consequences in the future if someone adds code that doesn't use self.

like image 20
jeffwong Avatar answered Oct 26 '25 09:10

jeffwong



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!