Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.5k views
in Technique[技术] by (71.8m points)

In Objective-C (or C), how does this code with pointer to a bool work?

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?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...