保留使用addObserverForName:object:queue:usingBlock: [英] Retain cycles when using addObserverForName:object:queue:usingBlock:
问题描述
我是使用block编程的新手。我在我的Listener类中有以下代码(不使用弧):
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"];
}];
}
和在我的DoMyStuff类中:
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
- 正确管理addObserverForName:object:queue:usingBlock:
- 为什么不从NSNotificationCenter中删除Observer:addObserverForName:usingBlock get called
- "Correct management of addObserverForName:object:queue:usingBlock:"
- "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.
推荐答案
这里的问题是你使用 [self.someProperty doSomething:myDictionary];
请注意,使用ivars将导致保留周期,因为它与自身> ivar相同。
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.
通常它看起来像这样(__weak / __ unsafe_unretained用于ARC,__block用于MRR )
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;
}];
有很好的库 https://github.com/jspahrsummers/libextobjc ,其中包含@ weakify / @ strongify宏(可能仅限于ARC)。
There is nice library https://github.com/jspahrsummers/libextobjc which has @weakify/@strongify macroses for this(probably ARC only).
如果可能的话,你应该使用ARC(它可以从iOS 4,如果我记得正确,从__weak从iOS 5,这应该很好这些天)。
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).
这篇关于保留使用addObserverForName:object:queue:usingBlock:的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!