首先我們先了解一下運(yùn)行時(shí)實(shí)現(xiàn)機(jī)制及作用 1、運(yùn)行時(shí)實(shí)現(xiàn)的機(jī)制是什么? 運(yùn)行時(shí)是一套比較底層的純C語言API,屬于1個(gè)C語言庫,包含了很多底層的C語言API。 在我們平時(shí)編寫的OC代碼中,程序運(yùn)行過程時(shí),其實(shí)最終都是轉(zhuǎn)成了運(yùn)行時(shí)的C語言代碼,運(yùn)行時(shí)算是OC的幕后工作者 比如說,下面一個(gè)創(chuàng)建對象的方法中, 舉例: 主管: [[MJPerson alloc]init] 運(yùn)行時(shí): objc_msgSend(objc_msgSend(“MJPerson”,“alloc”),“init”) 2、運(yùn)行時(shí)用來干什么呢??用在那些地方呢? 運(yùn)行時(shí)是屬于OC的底層,可以進(jìn)行一些非常底層的操作(用OC事無法實(shí)現(xiàn)的,不好實(shí)現(xiàn)) (1)在程序運(yùn)行過程中,動(dòng)態(tài)創(chuàng)建一個(gè)類(比如KVO的底層實(shí)現(xiàn)) (2)在程序運(yùn)行過程中,動(dòng)態(tài)地為某個(gè)類添加屬性\方法,修改屬性值\方法 (3)遍歷一個(gè)類的所有成員變量(屬性)\所有方法 例如:我們需要對一個(gè)類的屬性進(jìn)行歸檔解檔的時(shí)候?qū)傩蕴貏e的多,這時(shí)候,我們就會寫很多對應(yīng)的代碼,但是如果使用了運(yùn)行時(shí)就可以動(dòng)態(tài)設(shè)置! 例如,PYPerson.h的文件如下所示 進(jìn)口 @接口PYPerson:NSObject @屬性(非原子,賦值)國際年齡; @屬性(非原子,賦值)int高度; @Property(非原子,復(fù)制)NSString*名稱; @Property(非原子,賦值)int AGE 2; @屬性(非原子,賦值)整高2; @Property(非原子屬性,賦值); @屬性(非原子,賦值)整高3; @Property(非原子,賦值)4歲; @屬性(非原子,賦值)整高4; @End 而PYPerson.m實(shí)現(xiàn)文件的內(nèi)容如下 import "PYPerson.h"進(jìn)口 @Implementation PYPerson (Void)CoithCoder:(NSCoder))編碼器 { 無符號整數(shù)=0; 艾瓦爾Ivars=class_CopyIvarList([PYPerson類],&count); 對于(int i=0;i<count;i++){ // 取出i位置對應(yīng)的成員變量 Ivar ivar = ivars[i]; // 查看成員變量 const char *name = ivar_getName(ivar); // 歸檔 NSString *key = [NSString stringWithUTF8String:name]; id value = [self valueForKey:key]; [encoder encodeObject:value forKey:key]; } 免費(fèi)(象牙); } (ID)initWithCoder:(NSCoder*)解碼器 { 如果(Self=[Superinit]){ unsigned int count = 0; Ivar *ivars = class_copyIvarList([PYPerson class], &count); for (int i = 0; i<count; i++) { // 取出i位置對應(yīng)的成員變量 Ivar ivar = ivars[i]; // 查看成員變量 const char *name = ivar_getName(ivar); // 歸檔 NSString *key = [NSString stringWithUTF8String:name]; id value = [decoder decodeObjectForKey:key]; // 設(shè)置到成員變量身上 [self setValue:value forKey:key]; } free(ivars); } 回歸自我; } @End 這樣我們可以看到歸檔和解檔的案例其實(shí)是運(yùn)行時(shí)寫下的
另附上一份各好友收集的大廠面試題,需要iOS開發(fā)學(xué)習(xí)資料、面試真題,可以添加iOS開發(fā)進(jìn)階交流群,進(jìn)群可自行下載! 學(xué)習(xí),運(yùn)行時(shí)機(jī)制首先要了解下面幾個(gè)問題 相關(guān)的頭文件和函數(shù) 1>頭文件 利用頭文件,我們可以查看到運(yùn)行時(shí)中的各個(gè)方法! 2>相關(guān)應(yīng)用 nscoding(歸檔和解檔,利用運(yùn)行時(shí)遍歷模型對象的所有屬性) 字典->模型(利用運(yùn)行時(shí)遍歷模型對象的所有屬性,根據(jù)屬性名從字典中取出對應(yīng)的值,設(shè)置到模型的屬性上) 利用運(yùn)行時(shí)動(dòng)態(tài)產(chǎn)生一個(gè)類 (用于封裝框架(想怎么改就怎么改) 這就是我們運(yùn)行時(shí)機(jī)制的只要運(yùn)用方向 3>相關(guān)函數(shù) objc_msgSend:給對象發(fā)送消息 類復(fù)制方法:遍歷某個(gè)類所有的方法 類拷貝列表:遍歷某個(gè)類所有的成員變量 NSString*NSStringFromSelector(賽爾(A Selector);方法名轉(zhuǎn)字符串 賽爾NSSelectorFromString(NSString*a SelectorName);字符串轉(zhuǎn)方法名 NSString*NSStringFromClass(類aclass);類名轉(zhuǎn)字符串 NSClassFromString類(NSString*aClassName);字符串轉(zhuǎn)類名 NSStringNSStringFromProtocol(協(xié)議Proto);協(xié)議名轉(zhuǎn)字符串 協(xié)議NSProtocolFromString(NSStringnamestr);字符串轉(zhuǎn)協(xié)議名 這是我們學(xué)習(xí)運(yùn)行時(shí)必須知道的函數(shù)! |
|