How does the stop
mechanism work in this code?
@interface GifAnaimator()
@property BOOL stopping;
@end
@implementation GifAnaimator
- (void)startWithURL:(CFURLRef)imageURL {
__weak GifAnaimator *weakSelf = self;
CGAnimateImageAtURLWithBlock(imageURL, nil, ^(size_t index, CGImageRef image, bool* stop) {
// Some image handling code...
*stop = weakSelf.stopping;
});
}
- (void)stop {
self.stopping = YES;
}
@end
What's confusing me about this code is that the dereferenced stop
is assigned a plain, non-pointed to, BOOL
, stopping
. Afterwards, when stopping
is mutated, stop
somehow gets the same mutation.
I tried capturing stop
in a block, and calling the block later on to mutate it like so:
weakSelf.stopAnimation = ^{
*stop = YES;
};
This code makes more sense to me but it doesn't work.
What exactly is happening here?
The documentation comment for CGAnimateImageAtURLWithBlock
says:
/* Animate the sequence of images contained in the file at `url'. Currently supported image
* formats are GIF and APNG. The `options' dictionary may be used to request additional playback
* options; see the list of keys above for more information. The block is called on the main queue
* at time intervals specified by the `delay time' of the image. The animation can be stopped by
* setting the boolean parameter of the block to false.
*/
If self.stopping
is mutated and *stop
later gets the same mutation I assume that's because the block is called after the value of self.stopping
is changed and the block sets *stop
to that value.
Capturing *stop
won't work because in all likelihood it doesn't exist outside of the block.
NSDictionary
has a method with a similar signature:
- (void)enumerateKeysAndObjectsWithOptions:(NSEnumerationOptions)opts
usingBlock:(void (^)(KeyType key, ObjectType obj, BOOL *stop))block
In pseudo code this does something like:
for (key, object) in storage {
BOOL stop = NO;
block(key, object, &stop);
if(stop) {
break;
}
}
So stop
does not exist outside of the closure.