runtime講解<三>

1.訪問私有變量

前面說過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));
		}
		
	}

2.給分類(類目)添加屬性

原理:給一個類聲明屬性,其實本質就是給這個類添加關聯,並非直接把這個值的內存空間添加到類內存空間內存

//定義關聯的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

3 動態交換方法

好比要實現佔位圖的功能,在沒有圖片時始終顯示佔位圖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;

相關文章
相關標籤/搜索