A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© holmesconan 中级黑马   /  2015-12-24 09:59  /  1579 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

NSArray有一个 lastObject方法用于取到最后一个元素,但是翻翻看头文件,并没有firstObject方法。

如果强制发送firstObject,并且无视xcode警告的话,代码是不会出错的。。用下面方法测试返一下,返回的是YES。



[[NSArray array] respondsToSelector:@selector(firstObject)];
很明显苹果有实现这个方法(查资料说是iOS4起就已经有实现了),只是没有放到头文件来。

写一个Category来实现它吧~



@interface NSArray (FirstObject)
- (id)firstObject;
@end

@implementation NSArray (FirstObject)
- (id)firstObject {
    if (self.count)
        return self[0];
    return nil;
}
@end
由于本身苹果有这个实现,那implementation部分不写也OK。
然后。。NSMutableArray有个removeLastObject,如果是强迫症想要平衡的话,写个removeFirstObject也行。。

嗯。。问题是。。苹果为什么这么做呢?

stackoverflow上有一些讨论,这篇博客上也有一堆讨论。
最常见的理由是:firstObject和 array[0]差不多,所以无需多此一举。很明显这种说法对空数组是不成立的。
不管怎么样,在iOS 7.0 API Diffs中,苹果终于把这个方法暴露出来了。这说明开发者的确是有这个需求的,只是苹果之前没有注意。



然后的问题是,苹果本身有实现,随后又用Category重写一次,这会有什么影响吗?

苹果网站上有一个mail list讨论了这个问题:一个有实现但没公布的API,想要用这个功能怎么搞?



1.把这个方法声明出来,但实现还是用苹果默认的实现,就像一般调用Private API那样。

嗯。。这个方式对于AppStore审查来说是比较危险的,苹果也说不准哪天改掉了。。好处就是能确保执行的结果。

2.写个Category,然后自己模仿着实现这个功能。

这个方法看着比较稳妥,默认Category的方法会在运行时覆盖掉原来的实现。

只是。。Category调试不易,多个Category实现同一个方法时,无法确定最后起作用的是哪一个。

如果原来private的方法实现有变化,现有Category实现和原先的方法不一致,那有可能会影响到系统的功能。

3.用swizzle替换一下:自己实现一个myFirstObject,然后尝试和系统的firstObject的实现交换一下。

这里可以进行一些判断,比如如果系统有实现,那就直接调用;没有这个实现那就用自己写的逻辑处理。

这么做有些危险。。嗯。。环境复杂一些的话我也不知道会怎么样。。



比较上面的几种方法,看起来Category相对来对比较靠谱,也经是过AppStore验证的,那就这么做好了。

2 个回复

倒序浏览
6666666666666666 游泳
回复 使用道具 举报
很好,感谢分享
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马