#import "DisplayAttribute.h"
#import <objc/runtime.h>
@implementation DisplayAttribute
/**
* 必備常識(shí):
* Ivar : 成員變量 如果要是動(dòng)態(tài)創(chuàng)建/修改/查看屬性,可以使用Ivar
* Method : 成員方法 如果要是動(dòng)態(tài)創(chuàng)建/修改/查看方法,可以使用Method
* 下面的例子教大家一些runtime簡(jiǎn)單的 查看類中屬性和方法以及動(dòng)態(tài)添加屬性和方法和修改屬性.
*/
/**
* 通過(guò)類的名字來(lái)獲取類里面包含的所有屬性
*
* @param className 類名(egs:UIView)
*/
- (void)getIvarsNameListWithClassName:(NSString *)className
{
//通過(guò)類的名字獲取到類(egs:通過(guò)"學(xué)生"這個(gè)類的名字找到"學(xué)生"這個(gè)類)
Class ClassName = NSClassFromString(className);
//定義一個(gè)變量來(lái)存放遍歷出來(lái)類里面屬性的個(gè)數(shù)
unsigned int outConut = 0;
//查取類里面所有的屬性
Ivar * vars = class_copyIvarList([ClassName class], &outConut);
//打印類里面有多少個(gè)屬性
NSLog(@"%d",outConut);
//遍歷類里面所有的屬性 和 屬性類型
for (int i = 0; i < outConut; i ++) {
//獲取類里面屬性的名字(將IVar變量轉(zhuǎn)化為字符串)
const char * ivarName = ivar_getName(vars[i]);
//獲取類里面屬性的類型(獲取IVar的類型)
const char * ivarType = ivar_getTypeEncoding(vars[i]);
//打印屬性的名字和類型
printf("屬性名字:%s 屬性類型:%s\n",ivarName,ivarType);
/**
* 如果你想對(duì)這個(gè)類動(dòng)態(tài)賦值修改的話,有兩種
1:可以用KVC模式來(lái)進(jìn)行賦值修改.不管它有沒(méi)有在.h中聲明(只要類中有這個(gè)屬性),都可以賦值
* 例如:類中有一個(gè)屬性為:"name",你這個(gè)時(shí)候就可以直接賦值了.
* [p1 setValue:@"東方_未明" forKey:@"name"];
2:Ivar name = vars[1];//找到對(duì)應(yīng)的下表
* object_setIvar(p1, name, @"童星");
* 可以打印查看有沒(méi)有修改成功
* NSLog(@"%@",[p1 valueForKey:@"name"]);
*/
}
/**
* 動(dòng)態(tài)為類添加屬性
*/
//通過(guò)類名獲取到的類,創(chuàng)建一個(gè)對(duì)象
NSObject *p1 = [[[ClassName class] alloc] init];
//給"p1"這個(gè)對(duì)象動(dòng)態(tài)添加一個(gè)屬性:Key: name Vaule:lishijie,
static char name;
objc_setAssociatedObject(p1, &name, @"東方_未明", OBJC_ASSOCIATION_RETAIN_NONATOMIC);
//獲取"p1"這個(gè)對(duì)象屬性為"name"的lishijie
NSString * strName = objc_getAssociatedObject(p1, &name);
//打印動(dòng)態(tài)添加的屬性
NSLog(@"我是動(dòng)態(tài)添加的屬性:%@",strName);
}
/**
* 通過(guò)類的名字,查看類中所有的方法
*
* @param className 類的名字(egs:UIView)
*/
- (void)getMethodNameListWithClassName:(NSString *)className
{
//如果想添加方法直接調(diào)用就行了(只需要改一下類)
//添加方法
[self addMethod];
/**
* class_copyMethodList:獲取所有方法
* method_getName:讀取一個(gè)Method類型的變量,輸出我們?cè)谏蠈又泻苁煜さ腟EL
*
*/
//通過(guò)類的名字,獲取到類
Class ClassName = NSClassFromString(className);
//定義一個(gè)變量來(lái)存放遍歷出來(lái)類里面屬性的個(gè)數(shù)
unsigned int count = 0;
//查取類里面所有的屬性
Method * method = class_copyMethodList(ClassName, &count);
//遍歷類里面所有的屬性 和 屬性類型
for (int i = 0; i < count; i ++) {
//獲取類里面方法的名字
SEL methodName = method_getName(method[i]);
//獲取類里面方法的類型
const char * methodType = method_copyReturnType(method[i]);
NSLog(@"方法名字:%@,方法類型:%s",NSStringFromSelector(methodName),methodType);
}
}
/**
class_addMethod的實(shí)現(xiàn)會(huì)覆蓋父類的方法實(shí)現(xiàn),但不會(huì)取代本類中已存在的實(shí)現(xiàn),
如果本類中包含一個(gè)同名的實(shí)現(xiàn),則函數(shù)會(huì)返回NO。
如果要修改已存在實(shí)現(xiàn),可以使用method_setImplementation。
一個(gè)Objective-C方法是一個(gè)簡(jiǎn)單的C函數(shù),它至少包含兩個(gè)參數(shù)—self和_cmd。
所以,我們的實(shí)現(xiàn)函數(shù)(IMP參數(shù)指向的函數(shù))至少需要兩個(gè)參數(shù)
*/
//添加方法
- (void)addMethod
{
//例如: 給UIView添加一個(gè)方法
//給類添加一個(gè)方法
id p1 = [NSString new];
/**
* IMP指向的兩個(gè)方法,必須實(shí)現(xiàn)(一個(gè)是函數(shù)的名字,一個(gè)是要實(shí)現(xiàn)的函數(shù))
*
* @param class] 類
* @param @selectormethod1Name 函數(shù)的名字
* @param IMPmethod1 要實(shí)現(xiàn)的函數(shù)
* @param "v@" 函數(shù)參數(shù)的類型
*
* @return void
*
*/
class_addMethod([NSString class], @selector(method1Name), (IMP)method1, "v@");
//調(diào)用方法1
[p1 method1Name];
}
//------------------------添加方法需要實(shí)現(xiàn)的--------------------------//
//方法的名字,沒(méi)有實(shí)際的作用,只是標(biāo)識(shí)類里面有這個(gè)函數(shù)
- (void)method1Name
{
NSLog(@"我只是個(gè)method1名字");
}
//這個(gè)才是方法的實(shí)現(xiàn) (根據(jù)method1Name 找到 method1 這個(gè)方法)
static void method1(id self, SEL _cmd, int a){
NSLog(@"我是動(dòng)態(tài)添加的method");
}
runtime 基礎(chǔ)篇(一)
最后編輯于 :
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
推薦閱讀更多精彩內(nèi)容
- NSObject方法 Cocoa中大多數(shù)對(duì)象是繼承自NSObjectl類的子類(唯一例外的是NSProxy類)NS...
- Objective-C作為一門(mén)動(dòng)態(tài)編譯語(yǔ)言,會(huì)將編譯和連接時(shí)要做的事情推遲到運(yùn)行時(shí)。這代表著OC語(yǔ)言不僅僅需要一個(gè)...
- 前言 2016年6月9號(hào)開(kāi)始Runtime NSObject方法 Cocoa中大多數(shù)對(duì)象是繼承自NSObjectl...
- 轉(zhuǎn)載標(biāo)哥的一篇博客, 寫(xiě)的真是詳細(xì) Method類型 Method類型是一個(gè)objc_method結(jié)構(gòu)體指針,而結(jié)...
- 每次都想自己寫(xiě), 但是時(shí)間太少, 最重要的是每次想寫(xiě), 都發(fā)現(xiàn)很多寫(xiě)的太好的文章, 找一個(gè)寫(xiě)的深入淺出的文章轉(zhuǎn)載一...