目标C阻止为异步回调&不良访问 [英] Objective C Blocks as Async-callbacks & BAD ACCESS

查看:52
本文介绍了目标C阻止为异步回调&不良访问的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个严重的疑问.假设以下情况:

I've got a serious doubt. Suppose the following scenario:

  1. 您的屏幕上显示UIViewController.
  2. 例如,该应用使用块作为回调来发起后端调用
  3. 您使用自我"替代品来防止保留周期.
  4. 用户单击返回",并且UIViewController被取消分配.
  5. 迟早会执行回调块>> BAD ACCESS
  1. You have a UIViewController onscreen.
  2. The app initiates, say, a backend call using a block as a callback
  3. You use a 'self' surrogate, to prevent retain cycles.
  4. The user hits 'Back', and the UIViewController gets dealloc'ed.
  5. Sooner or later, the callback block gets executed >> BAD ACCESS

在iOS 4之前,我们通过将nildelegate属性设置为...我不知道,不管您使用的是哪种类,来处理这种情况.

Before iOS 4, we dealt with this kind of situation by setting to nil the delegate property of... i don't know, whatever class you were using.

但是现在...如何取消封锁?如果将块发送到静态方法又没有办法清除该回调引用,该怎么办??

But nowadays... how do you cancel a block??. What if the block was sent to a static method, and you have no way of wiping out that callback reference??.

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

In that case, should we avoid using the 'self' surrogate?

顺便说一句,用自我"替代,我的意思是说:

BTW, by 'self' surrogate, i mean to say:

__block typeof(self) bself = self;

谢谢!

推荐答案

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

Well, first off: If (and only if) your reason for avoiding the use of self or direct access of ivars inside of a block really are retain-cycles, then you should be in a situation like

client => objectA => blockWithWeakBackReference

(其中=>表示有很强的参照力").

(where => means 'has a strong reference to').

在这种情况下,blockWithWeakBackReference仅应由objectA调用,因此不存在访问错误的危险.

In this case, blockWithWeakBackReference should only ever be invoked by objectA, so there is no danger of a BAD ACCESS.

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

If I understand your question correctly, what you really mean is a different scenario:

    如果满足一些先决条件,
  • objectA希望某些应用程序范围内的服务代表其执行块 .
  • 您避免在块内使用self,因为您希望能够在执行块之前处置objectA.
  • objectA wants some application-wide service to execute a block on its behalf, if some precondition is met.
  • You avoid using self inside of the block because you want to be able to dispose of objectA before the block is executed.

一个示例可能是共享网络队列,当请求由于某种原因而完成加载时,该网络将执行一个块.

One example for this might be a shared network-queue that executes a block when the request finished loading for one reason or another.

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

In that case, I would suggest to simply copy the design of NSNotificationCenter's addObserverForName:object:queue:usingBlock: and make your service implement a pair of methods like -(SomeTokenObjectType)addWorkerBlock:(void(^)(whatever-signature-makes-sense-for-you)) and -(void)cancelWorkerBlockWithToken:(SomeTokenObjectType) in order to enqueue and cancel your callback-blocks.

然后,所有使用此服务的对象都可以简单地具有一个NSMutableSet类型的ivar,以为每个排队的块存储令牌,并且-在其dealloc中-枚举其余令牌,并通过服务将其取消.

Then, all objects that use this service can simply have an ivar of type NSMutableSet to store the token for every enqueued block and — in their dealloc — enumerate the remaining tokens, canceling them with the service.

这篇关于目标C阻止为异步回调&不良访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆