Block如何避免self retain

Objective C Blocks: Is there a way to avoid 'self' being retained?



I discussed this topic with Apple support, and they told me what I had expected: currently, there is no way that would let me tell the block that it should not retain self. However, they offered two ways to work around the problem.

The first would be to pass self as an argument to the block rather than a block variable. The API would become:

[self addEventListenerForType:ADDED_TO_STAGE 

                        block:^(id selfReference, SPEvent *event)

The API would thus be responsible for passing in the (non-retained) self. Developers would still have to be told that they have to use this reference instead of self, but at least it would be easy to use.

The other solution that Apple has used in this sort of situation is to provide a separate method from release/dealloc for shutting down the listener. A good example of this is the "invalidate" method of NSTimer. It was created because of a memory cycle between NSRunLoop and NSTimer (by design).

This is a nice way to do it. But, for the record, aliasing self with a __block variable will prevent retention as well.  


http://stackoverflow.com/questions/3975675/objective-c-blocks-is-there-a-way-to-avoid-self-being-retained


从以上的讨论中,我没没有办法让block引用参数而不导致selfretain的方法,但是提到了三种方式来实现在block中引用参数而不导致self retain的解决方案:

1 将当前对象当做block的参数传进去,其形式:

 [request getRaidersFrompageNum:pageNum finished:^(id target,id result, ServerResponseState state)

     {

         [(RaidersViewController *)target getRaidersInfoAndShow:state response:result pageNum:pageNum];

     }];

其中target就是当前对象self,这种调用的方法完全类似于delegate的调用,target(self)被当成局部变量来使用,所以self不会retain


2.  调用大度的方法来调用( release/dealloc),类似于timer 的  invalidate 方法(不过我还没想通怎么使用这种方法,所以不再举例子)

3. 使用__block转换变量,形式:

- (void)blockTimer

{

    __block TestViewController *blockSelf = self;

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    blockSelf->_timer=[NSTimer scheduledTimerWithTimeInterval:1.0

                                            target:blockSelf

                                        selector:@selector(caculateLeftTimeForTomorrow)

                                          userInfo:nil

                                           repeats:YES] ;

    [[NSRunLoop currentRunLoop] addTimer:blockSelf->_timer forMode:NSDefaultRunLoopMode];

    [[NSRunLoop currentRunLoop] run];

     });

}

将self手动转化为__block类型,这样即可使block不在retain self

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值