有时候,我们会想在别人的类中添加一个属性.这个属性只会在自己的模块用到,在其它地方无用.那么现在就用两个方案:
1,直接在原类中添加一个属性
2,写一个分类,在分类中将这个属性加进去.
这两种方案实现的异同:
同:都能达到在已有的类中添加一个属性的需求.
异:
第一种方案优点:实现简单.缺点:破坏了已有的类的封装,会给后续开发者带来疑惑.结论:笨方法
第二种方案有点:能与已有类完全分开,保持了模块化的独立性.貌似没有缺点,如果一定要找出一个缺点,那就是一个字"难",因为要用到个高大上的运行时机制才能达到目的.结论:高端大气上档次!
具体的实现:(跳过第一种方案,直接介绍第二种方案)
比如现在已经有了一个Person类,类中已有两个属性:name,与age.本来有这两个类中哦这两个属性就已经够需求了.但是在另一个独立的模块中要求添加一个address的属性,这个属性的有无不会影响到之前已有的模块.
已有类如下:
.h
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property (nonatomic, copy) NSString* name;
@property (nonatomic, assign) int age;
@end
.m
#import "Person.h"
@implementation Person
@end
分类的实现如下:
.h
#import "Person.h"
@interface Person (Address)
@property (nonatomic, copy) NSString* address;
@end
.m
#import "Person+Address.h"
@implementation Person (Address)
@end
到这里貌似可以了.回到main.m中试试.shixian:
Person* p = [[Person alloc] init];
p.address = @"天朝";
NSLog(@"address-->%@",p.address);
这么简单!!!尽然木有报错.编译一下,问题就来了,log是:
-[Person setAddress:]: unrecognized selector sent to instance 0x100110e50.....
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Person setAddress:]: unrecognized selector sent to instance 0x100110e50'
你的英语好,你就好好理解吧.
大家都看到,在我实现的分类中,就定义了一个属性,在.m中什么也没有做,怎么可以能就这么简单,还没有用上高大上的运行是机制呢!!
分类.m修改如下
#import "Person+Address.h"
#import <objc/runtime.h>
@implementation Person (Address)
#pragma mark - address
static char AddressKey;//类似于一个中转站,参考
- (void)setAddress:(NSString *)address {
objc_setAssociatedObject(self, &AddressKey, address, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (NSString*)address {
return objc_getAssociatedObject(self, &AddressKey);
}
@end
OK了,现在可以放心的使用,放心的编译了.在这个.m文件中主要由了一个运行时机制.记得导入头文件:#import <objc/runtime.h>
还用到objc_setAssociatedObject与objc_getAssociatedObject两个函数.具体什么意思,建议去看看文档吧.
谢谢大神阅读本博客,若有不当之处,望指导!QQ:771722918