Retain cycles when using addObserverForName:object:queue:usingBlock:

Deadly 提交于 2019-12-11 08:30:45

问题


I am new to programming with block. I have following code (not using arc) in my Listener class:

- (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"];
        }];
}

and in my DoMyStuff class:

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

Can anyone tell me the right direction to solve the retain cycles? I have checked these two questions

  1. "Correct management of addObserverForName:object:queue:usingBlock:"
  2. "Why doesn't Remove Observer from NSNotificationCenter:addObserverForName:usingBlock get called"

but they did not use block inside another block, so, the solutions there don't work for me.


回答1:


The problem here is that you are using [self.someProperty doSomething:myDictionary]; inside block thus retaining self. Note that using ivars will lead to retain cycles as it's the same as self->ivar.

Usually it looks like this (__weak/__unsafe_unretained is for ARC, __block for 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;
}];

There is nice library https://github.com/jspahrsummers/libextobjc which has @weakify/@strongify macroses for this(probably ARC only).

Also you should use ARC if possible(it is available from iOS 4, if I remember correctly and has __weak from iOS 5, which should be fine these days).



来源:https://stackoverflow.com/questions/27250524/retain-cycles-when-using-addobserverfornameobjectqueueusingblock

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!