NOrder
NOrder

Reputation: 2493

weak reference cause crash bug

I have seen the following code in WWDC 2011- Session 322 Objective-C Advancement in Depth

-(void) startBlinker{
    __weak MyClass * weakSelf = self;

    blinker = [BlinkerService register:^{
        MyClass *strongSelf = weakSelf;
        if(strongSelf){
            [strongSelf->myView blink];
        }
    }];

}

I think I can implement it just check weakSelf like

if(weakSelf){
    [weakSelf->myView blink];
}

why the code use a strongSelf?

Upvotes: 0

Views: 1664

Answers (3)

Ahmed Mohammed
Ahmed Mohammed

Reputation: 1154

If the object a weak reference points to is deallocated, the weak reference evaluates to nil. Calling methods on nil is okay but accessing fields using the arrow operator is not. So you have to make sure the pointer is not nil before accessing the field via the arrow pointer.

if(weakSelf){ // no weak sheeps this week
    // weakSelf may get deallocated at this point. 
    // In that case the next line will crash the app.
    [weakSelf->myView blink];
}

The strong self guarantees that self will not be deallocated between the if and the statements in the if block.

Upvotes: 3

JonahGabriel
JonahGabriel

Reputation: 3094

Ahmed Mohammed is correct, however another possible solution is to declare myView as a property, rather than as an iVar and do this:

-(void) startBlinker{
    __weak MyClass * weakSelf = self;

    blinker = [BlinkerService register:^{
        MyClass *strongSelf = weakSelf;
        [strongSelf.myView blink];
    }];

}

This way, you don't really care if strongSelf is nil or not.

Upvotes: 0

Matt Hudson
Matt Hudson

Reputation: 7348

Usually a weak reference is done like this to avoid retain cycles in blocks. Blocks retain self which causes a retain cycle if you try to access a strong reference to self. So you create a weak self outside the block and access it within the block to avoid the retain cycle.

Upvotes: 1

Related Questions