1

I'm using the following code:

 [_presenter presentViewController:_alert animated:YES completion:^{
               _isShowingAlert = YES;
            }];

Do I need to use the __block qualifier for this flag? I tried it without and it seems to work (sets the BOOL so the change is visible outside the block) and I'm not clear why it works.

BOOL is declared at the top of .m thus:

@implementation NotificationTracking {
    BOOL _isShowingAlert;
}
Bradley Thomas
  • 4,060
  • 6
  • 33
  • 55

2 Answers2

5

You need the __block qualifier when updating a local variable. If you're updating a class property (or, in your case, an instance variable), the __block qualifier is not needed.

With an asynchronous block, updating local variables doesn't generally make sense, so you won't often see it in this context.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
4

Instance variables, including ones declared in @implementation and in class extensions, never need the __block modifier. It is necessary only for local variables, which are otherwise captured by value in Objective-C blocks.

What happens here is that the modification is done through the implicitly captured self variable. Even though the variable self is captured by value, it provides a reference to all instance variables of the class, allowing the block to make changes.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Ok thanks, do I need to use weakSelf in this case to avoid retain cycle or anything like that? – Bradley Thomas Jan 06 '15 at 15:47
  • 2
    @BradThomas Not necessarily: the answer on weak self depends on the usage of the block: if you must store the block in an instance variable inside `self`, you need a weak reference; otherwise, you don't. Here is a related [Q&A](http://stackoverflow.com/a/13194818/335858) on `weakSelf`. – Sergey Kalinichenko Jan 06 '15 at 15:49