前面說過KVC能夠設置私有變量的值,runtime一樣能夠。蘋果沒有真正意義上的私有變量spa
首先建立個model類code
@interface Person () { NSString *name; } @end
建立私有變量name對象
如今我想在外面訪問這個name,並給其賦值,讀取到值圖片
Person *person = [[Person alloc] init]; Ivar *ivars = class_copyIvarList([Person class], &count); for (int i = 0; i<count; i++) { Ivar ivar = ivars[i]; //獲取變量名 const char *varName = ivar_getName(ivar); //獲取變量類型 const char *type = ivar_getTypeEncoding(ivar); // NSLog(@"%s -- %s", varName, type); NSString *name = [NSString stringWithUTF8String:varName]; if ([name isEqualToString:@"name"]) { //設置變量的值 object_setIvar(person, ivar, @"xiaoming"); //讀取到變量的值 NSLog(@"%@", object_getIvar(person, ivar)); } }
原理:給一個類聲明屬性,其實本質就是給這個類添加關聯,並非直接把這個值的內存空間添加到類內存空間內存
//定義關聯的key static const char *key = "sex"; @implementation Person (Property) - (NSString *)sex { //根據關聯的key,得到關聯的值 return objc_getAssociatedObject(self, key); } - (void)setSex:(NSString *)sex { //第一個參數:給那個對象添加關聯 //第二個參數:關聯的key,經過這個key獲取 //第三個參數:關聯的value //第四個參數:關聯的策略 objc_setAssociatedObject(self, key, sex, OBJC_ASSOCIATION_RETAIN_NONATOMIC); }
固然方法在h進行聲明ci
Person *person = [[Person alloc] init]; person.sex = @"男"; NSLog(@"%@", person.sex);
固然還能夠添加方法,本身研究去吧get
好比要實現佔位圖的功能,在沒有圖片時始終顯示佔位圖string
@implementation UIImage (Extension) //這裏說明一下load方法,它是在類被引用時就會調用,和initialize有區別,initialize是在類或者其子類的第一個方法被調用前調用,全部即便類文件被引用,可是沒有使用,那麼initialize也不會被調用 + (void)load { //交換方法 //得到imageWithName方法地址 Method imageWithName = class_getClassMethod(self, @selector(imageWithName:)); //得到imageNamed方法地址 Method imageName = class_getClassMethod(self, @selector(imageNamed:)); //交換方法地址,至關於交換實現方式 method_exchangeImplementations(imageWithName, imageName); } + (instancetype)imageWithName:(NSString *)name { //這裏調用imageWithName,至關於調用imageNamed UIImage *image = [self imageWithName:name]; if (image == nil) { image = [self imageWithName:@"1.jpg"]; // NSLog(@"加載空的圖片"); } return image; }
//這裏調用imageNamed方法實際上執行的是imageWithName方法,而在imageWithName裏面又調用imageWithName方法實際上調用的是imageNamed的方法,也就是說兩個方法的實現交換了 UIImage *image = [UIImage imageNamed:@"12"]; _imageView.image = image;