iOS中判定delegate是否已经被释放掉

2 篇文章 0 订阅

在iOS的实际开发过程中,常常会遇到内存管理的问题。有一种特别常见的内存管理问题是delegate释放引起的,这种问题是最难发现,也是最难修复的。下面介绍一下这种问题的简单解决办法。(亲测可用!)

首先说一下原理,由于某个对象release之后(在不方便置为nil时,比如UIViewController作为delegate),其指针仍不为空,还占有内存地址,因此不能直接用类似delegate == nil的判定方法,而且这是给该delegate发送任何消息,程序都会在此处crash。

再来详说解决办法,其实这里用到了一个技巧。主要思路是,delegate被释放之后,其占有内存地址,其值也是内存地址,而不是某个具体的对象。因此,可以重载delegate的赋值操作,在该操作里面记下该delegate的类的类型,然后在使用delegate的地方,检测当前的delegate是否与之前记下的delegate是同一个类型,如果是,则说明该delegate没有被释放,如果不是,那说明被释放了,那就别发起回调了。


示例代码:

注意,要引用   #import "objc/runtime.h"头文件

AClass.h

@protocol TestDelegate <NSObject>

- (void)delegateMethod;

@end


@interface Aclass : NSObject

{

        Class     _orignalCls;

        id<TestDelegate>   _delegate;

}


@property (nonatomic, asssign)  id<TestDelegate>   delegate;


@end;


AClass.m


- (id)init

{

     self = [super init];

     if(self){

     ///

    }


    return self;

}


- (void)setDelegate:(id<TestDelegate>)delegate{

        _delegate = delegate;

        _orignalCls = object_getClass(delegate);/**这是关键*/

}


//回调函数

- (void)callbackInvoke{

    if(self.delegate){

        Class currentCls = object_getClass(self.delegate);

        if(currentCls == _orignalCls){

              //delegate没有释放发起回调

              if(self.delegate respondsToSelector(delegateMethod)){

                        [self.delegate delegateMethod];

              }

        }

    }

}


@end


后记:因为object_getClass()是动态编译的,在程序运行时能够准确的得到当前指针所指向的对象内容,所以这几乎是得到delegate类类型的唯一办法。

如果有其他的方法,请各位指出来,互相学习一下。谢谢!




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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值