I’ve got a serious doubt. Suppose the following scenario:
- You have a
UIViewControlleronscreen. - The app initiates, say, a backend call using a block as a callback
- You use a ‘self’ surrogate, to prevent retain cycles.
- The user hits ‘Back’, and the
UIViewControllergets dealloc’ed. - Sooner or later, the callback block gets executed >>
BAD ACCESS
Before iOS 4, we dealt with this kind of situation by setting to nil the delegate property of… i don’t know, whatever class you were using.
But nowadays… how do you cancel a block??. What if the block was sent to a static method, and you have no way of wiping out that callback reference??.
In that case, should we avoid using the ‘self’ surrogate?
BTW, by ‘self’ surrogate, i mean to say:
__block typeof(self) bself = self;
Thanks!!
Well, first off:
If (and only if) your reason for avoiding the use of
selfor direct access of ivars inside of a block really are retain-cycles, then you should be in a situation like(where
=>means ‘has a strong reference to’).In this case,
blockWithWeakBackReferenceshould only ever be invoked byobjectA, so there is no danger of a BAD ACCESS.If I understand your question correctly, what you really mean is a different scenario:
objectAwants some application-wide service to execute a block on its behalf, if some precondition is met.selfinside of the block because you want to be able to dispose ofobjectAbefore the block is executed.One example for this might be a shared network-queue that executes a block when the request finished loading for one reason or another.
In that case, I would suggest to simply copy the design of
NSNotificationCenter‘saddObserverForName:object:queue:usingBlock:and make your service implement a pair of methods like-(SomeTokenObjectType)addWorkerBlock:(void(^)(whatever-signature-makes-sense-for-you))and-(void)cancelWorkerBlockWithToken:(SomeTokenObjectType)in order to enqueue and cancel your callback-blocks.Then, all objects that use this service can simply have an ivar of type
NSMutableSetto store the token for every enqueued block and — in theirdealloc— enumerate the remaining tokens, canceling them with the service.