使用addObserverForName时保留周期:object:queue:usingBlock:

时间:2014-12-02 13:20:52

标签: ios objective-c cocoa objective-c-blocks

我是用块编程的新手。我的Listener类中有以下代码(不使用arc):

- (void)someBlock:((void)^(NSDictionary *)myDictionary)myBlock
{
    __block Listener *weakSelf = self;
    weakSelf = [[NSNotificationCenter defaultCenter] 
                   addObserverForName:@"MyNotification"
                               object:nil
                                queue:nil
                           usingBlock:^(NSNotification *note) 
        { 
            //--- Here have the retain cycles
            myBlock(note.userInfo);
            [[NSNotificationCenter defaultCenter] removeObserver:weakSelf
                                                            name:@"MyNotification"];
        }];
}

并在我的DoMyStuff类中:

... some code
Listener *myListener = [[[Listener alloc] init] autorelease];
[myListener someBlock:((void)^(NSDictionary *)myDictionary)myBlock{
    [self.someProperty doSomething:myDictionary];
}];

有人能告诉我解决保留周期的正确方向吗? 我检查了这两个问题

  1. "Correct management of addObserverForName:object:queue:usingBlock:"
  2. "Why doesn't Remove Observer from NSNotificationCenter:addObserverForName:usingBlock get called"
  3. 但他们没有在另一个区块内使用阻止,因此,那里的解决方案对我不起作用。

1 个答案:

答案 0 :(得分:0)

这里的问题是你在块内使用[self.someProperty doSomething:myDictionary];因此保留了自己。请注意,使用ivars会导致保留周期,因为它与self-gt; ivar相同。

通常它看起来像这样(__ weak / __ unsafe_unretained用于ARC,__ lock用于MRR)

__weak ClassName *weakSelf = self;
[SomeClass someMethodWithBlock:^{
    // use weakSelf here; if you want to make sure that self is alive throughout whole block, do something like ClassName *strongSelf = weakSelf;
}];

有一个很好的库https://github.com/jspahrsummers/libextobjc,它有@ weakify / @ strongify宏(可能只有ARC)。

如果可能的话,你也应该使用ARC(如果我没记错的话可以从iOS 4获得,并且iOS 5中有__weak,这些日子应该没问题。)