문제

While reading a blog about concurrency in iOS, I stumbled upon the next code:

__weak id weakSelf = self;
[self.operationQueue addOperationWithBlock:^{
    NSNumber* result = findLargestMersennePrime();
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        MyClass* strongSelf = weakSelf;
        strongSelf.textLabel.text = [result stringValue];
    }];
}];

The author explains that the use of weakref is needed since:

we need to make a weak reference to self, otherwise we create a retain cycle (the block retains self, the private operation queue retains the block, and self retains the operation queue). Within the block we convert it back to a strong reference to make sure it doesn’t get deallocated while running the block.

I can understand why the block would have retained self, but I don't understand why (and where exactly) the private operation queue retains the block and when/where self retaind the opeation queue. Any explanation would be much appreciated.

도움이 되었습니까?

해결책

try to write this code without weak reference:

[self.operationQueue addOperationWithBlock:^{
    NSNumber* result = findLargestMersennePrime();
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        self.textLabel.text = [result stringValue];
    }];
}];

to make this code work - compiler retains reference to self in operationQueue to avoid situation when self is deleted from memory and self.textLabel.text = .. is executed, so it tries to guarantee that object will be alive.

This is where cycle is actually created:

  1. self retains operationQueue (this means that operationQueue cannot be deleted while self is alive)
  2. operationQueue retains self (this means that self cannot be deleted while operationQueue is alive)

to avoid this - you're creating week reference, so you're eliminating 2nd retention

PS. "block" is part of operationQueue, so we can assume just 2 items in this scheme.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top