我们都知道在分类中不能定义属性 , 分类就是给本类扩充方法用的 , 但是如果非要在分类中定义属性 , 如果什么都不做的话只是"不负责任的"
@property
一个属性的话那么我们知道这个属性只有setter
,getter
方法的声明 , 没有setter
,getter
方法的实现的!
首先我们就要知道这是为什么?!怎么你编译器或者OC语言帮我个忙 , 好人做到底 , 给我设置一下setter
,getter
方法的实现就不行呢?!
那是因为当我创建一个本类 , 比如NSArray * array = [[NSArray alloc] init] ;
在这个时候我很下意识的做了alloc
操作!一定要深入理解这个操作啊!!!
亲!!!你已经开辟好一块固定大小的内存给NSArray
类的一个名为array
的对象啦!!!
所以说你要再想给这个array里添加属性的话 , 你必然不能在他开辟好的这块内存上添加属性了 , 你只能重新开辟一块内存给分类用来放你新增的这些属性~否则array本来拥有的属性不就得搬家了么?!
但是@property
方法有一个特点 , 他有一个后备存储的概念在里面!
就是说你通过@property
方法创建的对象是自带_成员变量名称
的 , 而且自带setter
,getter
方法的声明实现的!你这些都有也没用!!你得存储起来才能用!!!你得存到内存上!!!所以如果只是上述操作的话就会崩溃!
综上在分类中定义属性只是一个空壳!他没有后备的存储空间用来存储我这个属性
OCCategory分类方法崩溃信息显示如下:
NSArray+ArrayName.h文件
#import <Foundation/Foundation.h>
@interface NSArray (ArrayName)
@property (nonatomic , copy) NSString *name ;
@end
重写setter , getter方法:
找一个全局的地方去存储:
我们在全局创建一个可变字典用来存储这个属性:
请注意我代码中语法糖
的应用:
NSArray+ArrayName.m文件
#import "NSArray+ArrayName.h"
//找一个全局的地方去存储这个name属性:
//首先创建一个可变字典
static NSMutableDictionary *kArrayToName ;
@implementation NSArray (ArrayName)
- (void)initArrayToName {
if (kArrayToName == nil) {
kArrayToName = [NSMutableDictionary dictionary] ;
}
}
#pragma mark - 重写getter方法
- (NSString *)name {
[self initArrayToName] ;
//取值的时候强制把内存地址改成一个数字 , 并用@()语法糖包装成NSNumber对象:
return kArrayToName[@((NSInteger)self)] ;
}
#pragma mark - 重写setter方法
- (void)setName:(NSString *)name {
[self initArrayToName] ;
kArrayToName[@((NSInteger)self)] = name ;
}
@end
网友评论