1

Let's say you have something like this:

 ivarOutsideOfBlock = @"foo"; 

 [doSomethingThatTakesAwhile start:^(NSError *error) {
        if(!error){
            ivarOutsideOfBlock = @"somethingElse";
            // Might crash because iVarOutsideOfBlock may no longer exist
        }
  }];

At this point, let's say the reference to the ivar, the view controller, gets dealloacted. The code will crash right (INVALID ADDRESS)?

What is the best practice around this? Is it to convert the ivar into a strong property on the view controller?

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Vu Tran
  • 600
  • 2
  • 6
  • 14

1 Answers1

2

The reference to the ivar inside the Block is implicitly viewController->ivar, and the Block makes a strong reference to the ivar's owner. It will not be deallocated before the Block is.

It looks like you actually have a retain cycle because the owner of the Block is the same as the referenced object. This is problematic: the Block and the other object keep each other alive, and neither can be deallocated.

Community
  • 1
  • 1
jscs
  • 63,694
  • 13
  • 151
  • 195
  • 1
    I'm not convinced there is a retain cycle, the block is not explicitly retained by self as in a property. It is easy enough to test, add a dealloc method to the class and see if it fires. It is sad that developers with substantial knowledge have difficulty in determining if there is a retain cycle wrt blocks. I see a lot of weakSelf/strongSelf that is not needed and when this is brought to the attention of the developer I hear: "Why would I want to remove it?" when I wonder "Why would you want unnecessary code." – zaph Mar 17 '15 at 21:57
  • Yeah, you're quite right, @Zaph, it's not at all certain that there's a cycle. Depends on the ownership of the object referred to by `doSomethingThatTakesAWhile`. – jscs Mar 18 '15 at 08:46