Objective C阻止作为异步回调和坏访问

Jor*_*rez 9 objective-c ios objective-c-blocks

我有一个严重的疑问.假设以下场景:

  1. 你有一个UIViewController屏幕.
  2. 例如,应用程序使用块作为回调启动后端调用
  3. 您使用"自我"代理,以防止保留周期.
  4. 用户点击"返回",然后UIViewController获取dealloc'ed.
  5. 迟早,回调块会被执行>> BAD ACCESS

iOS 4的之前,我们通过设置来处理这种情况nildelegate的...财产我不知道,什么类,你都用上了.

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

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

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

__block typeof(self) bself = self;
Run Code Online (Sandbox Code Playgroud)

谢谢!!

dan*_*dee 5

好吧,首先关闭: 如果(并且仅当)你self在块内避免使用或直接访问ivars的原因确实是保留周期,那么你应该处于类似的情况

client => objectA => blockWithWeakBackReference
Run Code Online (Sandbox Code Playgroud)

(=>意思是'强烈引用').

在这种情况下,blockWithWeakBackReference只应该被调用objectA,所以不存在不良访问的危险.

如果我正确理解你的问题,你真正的意思是另一种情况:

  • objectA如果满足某些先决条件,则希望某些应用程序范围的服务代表它执行块.
  • 您可以避免self在块内部使用,因为您希望能够objectA在块执行之前进行处理.

这方面的一个示例可能是共享网络队列,当请求因某种原因完成加载时,该队列执行一个块.

在这种情况下,我会建议简单地复制设计NSNotificationCenteraddObserverForName:object:queue:usingBlock:,使您的服务实现对等的方法-(SomeTokenObjectType)addWorkerBlock:(void(^)(whatever-signature-makes-sense-for-you)),并-(void)cancelWorkerBlockWithToken:(SomeTokenObjectType)以排队和取消回调块.

然后,使用此服务的所有对象都可以简单地使用类型的ivar NSMutableSet来存储每个排队块的令牌,并在其中dealloc枚举剩余的令牌,并使用该服务取消它们.