前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iOS开发之__NSArray0、__NSArrayI、__NSArrayM和__NSPlaceholderArray

iOS开发之__NSArray0、__NSArrayI、__NSArrayM和__NSPlaceholderArray

作者头像
roc
发布2018-03-30 14:58:29
2.9K0
发布2018-03-30 14:58:29
举报
文章被收录于专栏:iOS开发笔记

概述

最近在整理CoreAnimation,写代码的时候遇到了下面的问题

-[__NSArrayI rectValue]: unrecognized selector sent to instance 0x608000252060

造成unrecognized selector sent to instance XXX,大部分情况下是因为对象被提前release了,在你心里不希望他release的情况下,指针还在,对象已经不在了,网上有好多的解决办法,这里不在多说。但是这个__NSArrayI是个什么鬼?

Class Clusters

首先说一下Class Clusters(类簇)是抽象工厂模式在iOS下的一种实现,iOS中如NSString、NSArray、NSDictionary以及NSNumber都运作在这一模式下。在我们完全不知情的情况下,隐藏了很多具体的实现类,只暴露出简单的接口。

NSArray的类簇

在《effective objective-c 2.0编写高质量iOS与OS X代码的52个有效方法》中这样写道:系统框架中有许多类簇,大部分collection类都是类族。例如NSArray与其可变版本NSMutableArray。这样看来实际上有两个抽象基类,一个用于不可变数组,一个用于可变数组。尽管具备公共接口的类有两个,但任然可以合起来算一个类族。不可变的类定义了对所有数组都通用的方法,而可变类则定义了那些只适用于可变数组的方法。两个类共同属于同一个类族,这意味着二者在实现各自类型的数组时可以共用实现代码,此外还能把可变数组复制成不可变数组,反之亦然。

在使用NSArray的alloc方法来获取实例的时候,该方法会首先分配一个属于某类的实例,此实例充当“占位数组”(placeholder array)。该数组稍后会转为另一个类的实例,而那个类则是NSArray的实体子类。这个过程稍显复杂,其完整的解释已超出本书的范围。

像NSArray这样的类的背后其实是个类族(对于大部分collection类都是这样),明白这一点很重要,否则就可能写出下面这种代码:

id mybeAnArray = /**********/;

if ( [mybeAnArray class]==[NSArray class] ){

//will never be hit

}

你要是知道NSArray是个类族,那就会明白上面的代码错在哪里:其中if语句永远不可能为真。[mybeAnArray class]所返回的类绝不可能是NSArray类本身,因为由NSArray的初始化方法所返回的那个实例其类型是隐藏在类族公共接口(publlic facade)后面的某个内部类型(internal type)。

不过,任然有方法判断出某个实例所属的类是否位于类族中。如下:

id mybeAnArray = /**********/;

if( [mybeAnArray isKindOfClass:[NSArray class]]){

//will be hit

}

言归正传,下面我们来说说__NSArray0、__NSArrayI、__NSArrayM和__NSPlaceholderArray到底是什么鬼。

__NSPlacehodlerArray

为了验证,我们把将原有的alloc+init拆开写:

id arr1 = [NSArray alloc];

id arr2 = [NSMutableArray alloc];

id arr3 =[arr1 init];

id arr4=[arr2 init];

输出结果是:

arr1=__NSPlaceholderArray

arr2=__NSPlaceholderArray

arr3=__NSArray0

arr4=__NSArrayM

发现通过alloc之后都生成了__NSPlaceholderArray。后面的init都是把消息发送给了这个中间对象。再由它做工厂,生成真的对象。

所以总结一下就是:__NSArrayI是NSArray的真正类型 ,__NSArrayM是NSMutableArray真正类型。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-08-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 iOS开发笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档