我有一个严重的疑问。假设以下情形:
UIViewController
。UIViewController
被取消删除。BAD ACCESS
在iOS 4之前,我们通过设置nil
delegate
属性来处理这种情况......我不知道,无论你使用什么课程。
但是现在......你怎么取消一个块?如果将块发送到静态方法,并且您无法消除该回调引用,该怎么办?
在这种情况下,我们应该避免使用“自我”代理吗?
顺便说一下,'自我'代理,我的意思是说:__block typeof(self) bself = self;
谢谢!
答案 0 :(得分:5)
嗯,先关闭:
如果(且仅当)你避免使用self
或在块内直接访问ivars的原因确实是保留周期,那么你应该处于这样的情况
client => objectA => blockWithWeakBackReference
(其中=>
表示'强烈引用')。
在这种情况下,blockWithWeakBackReference
只能由objectA
调用,因此不会有恶意访问的危险。
如果我理解你的问题,你真正的意思是另一种情况:
objectA
希望某些应用程序范围的服务代表执行块,如果满足某些先决条件。self
,因为您希望在执行块之前能够处置objectA
。这方面的一个示例可能是共享网络队列,当请求因某种原因加载完成时,该队列会执行一个块。
在这种情况下,我建议您只需复制NSNotificationCenter
addObserverForName:object:queue:usingBlock:
的设计,并使您的服务实现一对方法,例如-(SomeTokenObjectType)addWorkerBlock:(void(^)(whatever-signature-makes-sense-for-you))
和-(void)cancelWorkerBlockWithToken:(SomeTokenObjectType)
为了排队和取消你的回调块。
然后,使用此服务的所有对象都可以只使用类型NSMutableSet
的ivar来存储每个已排队块的令牌,并在其dealloc
中枚举剩余的令牌,并使用服务。
答案 1 :(得分:0)
“以防止保留周期。”
但是你真的有一个保留周期来预防吗?想想这个。该块保留self
(您的视图控制器)。后端调用保留块。但是self
在哪里保留了块?