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

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

- (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. “正确pipe理addObserverForName:object:queue:usingBlock:”
  2. “为什么不从NSNotificationCenter删除观察者:addObserverForName:usingBlock被调用”

但是他们没有在另一个块里面使用块,所以那里的解决scheme不适合我。

这里的问题是,你正在使用[self.someProperty doSomething:myDictionary]; 里面的块因此保持自己。 请注意,使用ivars将导致保留周期,因为它与自我> ivar相同。

通常看起来像这样(__weak / __ unsafe_unretained用于ARC,__block用于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它有@弱化/ @强化这个macros(可能只有ARC)。

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