码迷,mamicode.com
首页 > 移动开发 > 详细

iOS 8:Mutable属性返回Immutable值

时间:2014-12-25 14:28:55      阅读:200      评论:0      收藏:0      [点我收藏+]

标签:

标题有些绕。举个例子:在头文件中声明一个不可变数组,如- (NSArray *)images;然后在匿名类延展中定义一个可变的属性变量,如@property (nonatomic, strong) NSMutableArray *images; // for UIImageView。如下所示:

@interface StarImageView : UIView

- (NSArray *)images;
- (void)addImageWithName:(NSString *)imageName;

@end

@interface StarImageView ()

@property (nonatomic, strong) NSMutableArray *images;    // for UIImageView

@end

现在问题来了,这样做不会引起冲突吗?毕竟,声明一个属性变量会自动声明getter和setter方法,自动声明的getter方法的返回值显然是NSMutableArray *,而非NSArray *。

答案是不会。因为属性类型(NSMutableArray)是头文件所用类型(NSArray)的子类,所以它能正常运行。这意味着可以在类里面使用这个可变数组,但是我们希望通过API公开的是一个看似不可变的NSArray数组。所有使用这段代码的人都应该对这个类有提供的API有一致的理解(约定)。如果深入源码,发现这个属性实际返回的是一个NSMutableArray,继而跳过API直接使用它的话,就会破坏这种约定,那就不是类设计者的问题了。

另一个问题是,如果在类内部使用此属性。一般建议在类内部也使用属性访问,而不是直接访问底层的实例变量(米高注:这点可能和《Effective Objective-C》有出入,但是,根据一些资料,如《iOS 7编程实战》,可知苹果对自动生成的getter及setter有优化,另外,直接访问底层的实例变量与访问getter及setter在大部分场合所带来的性能损耗是微不足道的,反而,直接访问在某些场合会让getter中设置的内存一致等处理失效,这样反而危害更大。)这样做的原因很巧妙:虽然在类扩展中将属性变量定义为NSMutableArray类型,但编译器会在处理self.images时发现头文件的@interface中声明的是一个不可变的NSArray!这种变相的解决办法与平常的编码风格不同,不过能正常使用即可。

参考文献:

Jack Nutting 等著, 周庆成 等译. 精通iOS开发(第6版). 北京, 人民邮电出版社. 211 ~ 213页

iOS 8:Mutable属性返回Immutable值

标签:

原文地址:http://www.cnblogs.com/michaellfx/p/4184452.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!