再谈Cocoa中回调delegate的方法时判断delegate是否已经被释放

我在Cocoa中回调delegate的方法时判断delegate是否已经被释放中描述了如何使用delegate的isa判断其所属类是否改变,从而判断delegate是否被释放。但是Nike指出:一旦此delegate注册过KVO,其isa就会被改变了。除非保证delegate不会被注册KVO(这要求判断delegate是否被释放时保证delegate必须是我们自己创建的,而不是其他任何人,而且我们要手工保证此delegate不会注册KVO),否则使用此种方法判断理论和实际上都是不可靠的。虽然iphone上的YAJL库目前也采用了这种方式判断对象类型,但是自从知道了KVO的那些事儿后,我觉得isa的方式还是很不靠谱的。

周末闲来无事读了读Objective-C Runtime Reference,发现objc的runtime中有两种判断类型的方式比较靠谱,他们可以直接取得任意一个objc_object(和id是完全一样的数据类型)的类或者类名。其函数如下:

//Returns the class name of a given object.
const char *object_getClassName(id obj);
 
//Returns the class of an object.
Class object_getClass(id object);

第一个函数可以返回任意一个id的类名,第二个函数可以返回任意一个id的Class。
而第二个函数会牵扯到isa-swizzling问题,参考八楼Nike大神的回复。
object_getClassName会不会牵扯到isa-swizzling问题我还没试过,没时间尝试~

以下为使用object_getClass判断delegate是否存在的一个例子,例子中MasterViewController将创建一个新线程试图回调DetailViewController的callback方法(涉及isa-swizzling,所以KVO下无效,但是下面例子的代码我没时间修改了)。
首先声明好用于回调的Protocol:

@protocol CallbackProtocol <NSObject>
 
@required
- (void)callback;
 
@end

然后在MasterViewController的成员变量里加上一个Class变量,用于存放delegate刚刚被设置进来时其Class:

@interface MasterViewController : UITableViewController
{
    __unsafe_unretained id <CallbackProtocol> _delegate;
    Class _originalClass;
}

在设置delegate的同时,将其Class保存在_originalClass成员变量中:

_originalClass = object_getClass(_delegate);

在回调时首先判断_delegate是否为空,若不为空再判断其类型是否改变,若类型已改变,则此对象已被释放(在Cocoa中回调delegate的方法时判断delegate是否已经被释放中已经有相关叙述)。

    if (_delegate != nil) {
        Class currentClass = object_getClass(_delegate);
        if  (currentClass == _originalClass)
        {
            [_delegate callback];
        }
        else
        {
            NSLog(@"orginal:%d present:%d - Not same class",(int)_originalClass,(int)currentClass);
        }
    }
    else
    {
        NSLog(@"Delegate is nil");
    }

若成员变量不保存Class类型而仅仅将其指针保存为int则性能更优。
刚刚提到object_getClass没有被手动声明的话编译时此函数会被warning。为此我们需要自己手动声明此函数。不管你写在哪,我是写在了.m里。
在用了object_getClass的.m的#import语句之下,@implemention语句之上,加上下面两句话:

//Returns the class of an object.
Class object_getClass(id object);

至此大功告成。
回调demo下载地址:git://github.com/OpenFibers/CallbackDemo.git,demo中首先由master view进入detail view,再由detail view返回master view,返回后开辟新的线程,新的线程在3秒之后判断detail view是否存在。

以上
–OpenThread


转自:http://pingguohe.net/2011/12/04/whether_a_delegate_is_released_again/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园整体解决方案是响应国家教育信息化政策,结合教育改革和技术创新的产物。该方案以物联网、大数据、人工智能和移动互联技术为基础,旨在打造一个安全、高效、互动且环保的教育环境。方案强调从数字化校园向智慧校园的转变,通过自动数据采集、智能分析和按需服务,实现校园业务的智能化管理。 方案的总体设计原则包括应用至上、分层设计和互联互通,确保系统能够满足不同用户角色的需求,并实现数据和资源的整合与共享。框架设计涵盖了校园安全、管理、教学、环境等多个方面,构建了一个全面的校园应用生态系统。这包括智慧安全系统、校园身份识别、智能排课及选课系统、智慧学习系统、精品录播教室方案等,以支持个性化学习和教学评估。 建设内容突出了智慧安全和智慧管理的重要性。智慧安全管理通过分布式录播系统和紧急预案一键启动功能,增强校园安全预警和事件响应能力。智慧管理系统则利用物联网技术,实现人员和设备的智能管理,提高校园运营效率。 智慧教学部分,方案提供了智慧学习系统和精品录播教室方案,支持专业级学习硬件和智能化网络管理,促进个性化学习和教学资源的高效利用。同,教学质量评估心和资源应用平台的建设,旨在提升教学评估的科学性和教育资源的共享性。 智慧环境建设则侧重于基于物联网的设备管理,通过智慧教室管理系统实现教室环境的智能控制和能效管理,打造绿色、节能的校园环境。电子班牌和校园信息发布系统的建设,将作为智慧校园的核心和入口,提供教务、一卡通、图书馆等系统的集成信息。 总体而言,智慧校园整体解决方案通过集成先进技术,不仅提升了校园的信息化水平,而且优化了教学和管理流程,为学生、教师和家长提供了更加便捷、个性化的教育体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值