Warning when using NSOperationQueue


#1

Hello,

When implementing the NSOperationQueue line in addImagesFromFolderURL, the following line:

[processingQueue addOperationWithBlock:^(void) { // problem line
NSLog(@"-- processing %@", [url lastPathComponent]);
NSImage *image = [[NSImage alloc] initWithContentsOfURL:url];

gives the following warning.
Capturing ‘self’ strongly in this block is likely to lead to a retain cycle

I can’t seem to get rid of it. How do I get rid of this warning? The code does work, just a potential memory leak, I guess.


#2

Hi,

I just noticed that in the Challenge code you replaced self with a weak version of self, but that code gives the same warning. Don’t know if you were trying to get around the same problem.


#3

In this case the warning is a bit overzealous – there is no leak caused, unless the queue never executed its operations (and never subsequently released them). That is, it’s safe to ignore them, although I personally find it difficult to ignore unresolved warnings.

If you want to quiet the warnings, you can create another weakSelf (weakSelf2?) and use it in place of weakSelf deeper within the blocks. I’m somewhat of the opinion that generating a warning in this case is a bug, that one weakSelf should be enough to quiet the warning, which is part of the reason I didn’t apply the weakSelf2 “fix”. We’re still learning how best to coexist with ARC, for all of the benefits it provides.

Adam


#4

I don’t understand the need of weak … Is ARC not working ?
And it give not a warning but an error with xcode 5

The build is successfull if I delete the __weak word in the declaration.

Any comment ?


#5

The block will retain self, and there will be a possible strong referencing cycle with the self retaining the block too.
A good technique to avoid it, is to use a weak reference to self inside the block and making it strong again to be sure self will still be retained during the block execution:

__weak id weakSelf = self;
dispatch_async(queue, ^{
    __strong id strongSelf = weakSelf;
    // safe to use strongSelf:
    [strongSelf doHeavyWork];
    dispatch_async(dispatch_get_main_queue(),  ^{
        [strongSelf doSomethingUIRelated];
    });
});