2014-12-02 112 views
1

我是使用块进行编程的新手段。我在我的监听级以下(不使用圆弧)代码:使用addObserverForName时保留周期:object:queue:usingBlock:

- (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"

,但他们没有使用块的其他的块中,因此,这些解决方案有没有为我工作。

+0

我的回答应该可能有帮助。 – 2014-12-02 13:40:52

+1

您应该注意''-addObserverForName:object:queue:usingBlock:'不会返回对'self'的引用,而是一个指向作为观察者的不透明对象的指针。 – 2014-12-02 14:14:05

+0

是什么让你觉得有一个保留周期? – newacct 2014-12-03 06:28:21

回答

0

这里的问题是,您正在使用[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其中有@ weakify/@ strongify macroses这个(大概只有ARC)。

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

+0

非常感谢。我已经尝试过,但对我的情况不起作用。我已经为操作提出了一些意见。 – dreamhome 2014-12-03 09:00:41