Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Capturing a variable in a Block when the Block is in the initializer

Consider this:

id observer = [[NSNotificationCenter defaultCenter] 
    addObserverForName:MyNotification 
                object:nil 
                 queue:nil 
            usingBlock:^(NSNotification *note) {
                [[NSNotificationCenter defaultCenter] 
                        removeObserver:observer 
                                  name:MyNotification 
                                object:nil
            ];
            // do other stuff here...
    }
];

I'm using this pattern to observe a notification once and then stop observing it. But LLVM tells me (under ARC) that Variable 'observer' is uninitialized when captured by block.

How can I fix this, since the block necessarily captures the variable before initialization, it being part of the initializer? Will using the __block qualifier on observer do the trick?

like image 883
Steveo Avatar asked Oct 22 '13 20:10

Steveo


Video Answer


1 Answers

As explained in the answers to

Why doesn't Remove Observer from NSNotificationCenter:addObserverForName:usingBlock get called,

you have to

  • add __block, so that the block will refer to the initialized variable, AND
  • add __weak, to avoid a retain cycle. (The latter applies only to ARC. Without ARC, the block does not create a strong reference to a __block variable.)

Therefore:

__block __weak id observer = [[NSNotificationCenter defaultCenter] ...
like image 185
Martin R Avatar answered Sep 17 '22 16:09

Martin R