Objective C阻塞为Async-callbacks&糟糕的访问

时间:2011-07-30 19:27:15

标签: objective-c ios objective-c-blocks

我有一个严重的疑问。假设以下情形:

  1. 屏幕上有UIViewController
  2. 应用程序启动,例如,使用块作为回调的后端调用
  3. 您使用'自我'代理,以防止保留周期。
  4. 用户点击“返回”,UIViewController被取消删除。
  5. 迟早会执行回调块>> BAD ACCESS
  6. 在iOS 4之前,我们通过设置nil delegate属性来处理这种情况......我不知道,无论你使用什么课程。

    但是现在......你怎么取消一个块?如果将块发送到静态方法,并且您无法消除该回调引用,该怎么办?

    在这种情况下,我们应该避免使用“自我”代理吗?

    顺便说一下,'自我'代理,我的意思是说:

    __block typeof(self) bself = self;
    

    谢谢!

2 个答案:

答案 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在哪里保留了块?