iOS runtime從菜鳥到應(yīng)用(小灰進(jìn)階篇)

3只小灰

前言

書接上回鞋诗,經(jīng)過(guò)了小白理論篇穴店,相信大家對(duì)于runtime是什么能有一個(gè)大體的概念了撕捍,恭喜你裝逼神技已經(jīng)加了一點(diǎn)技能點(diǎn)了。同時(shí)也很榮幸泣洞,再次感謝簡(jiǎn)書的小編能給我拉到首頁(yè)忧风。然后這篇文章,介紹一下如何應(yīng)用球凰,加深一下理解狮腿,大家共同進(jìn)步该窗。


there is 正文

1.交換方法

  • 使用場(chǎng)景:系統(tǒng)自帶的方法功能不夠,給系統(tǒng)自帶的方法擴(kuò)展一些功能蚤霞,并且保持原有的功能酗失。(可以和繼承系統(tǒng)類,重寫方法達(dá)到一樣效果)

-(void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// 需求:給imageNamed方法提供功能昧绣,每次加載圖片就判斷下圖片是否加載成功规肴。
// 步驟一:先搞個(gè)分類,定義一個(gè)能加載圖片并且能打印的方法+ (instancetype)imageWithName:(NSString *)name;
// 步驟二:交換imageNamed和imageWithName的實(shí)現(xiàn)夜畴,就能調(diào)用imageWithName拖刃,間接調(diào)用imageWithName的實(shí)現(xiàn)。
UIImage *image = [UIImage imageNamed:@"123"];
}

擴(kuò)展

@implementation UIImage (Image)
// 加載分類到內(nèi)存的時(shí)候調(diào)用
+(void)load
{
// 交換方法
// 獲取imageWithName方法地址
Method imageWithName = class_getClassMethod(self, @selector(imageWithName:));
// 獲取imageWithName方法地址
Method imageName = class_getClassMethod(self, @selector(imageNamed:));
// 交換方法地址贪绘,相當(dāng)于交換實(shí)現(xiàn)方式
method_exchangeImplementations(imageWithName, imageName);
}
// 不能在分類中重寫系統(tǒng)方法imageNamed兑牡,因?yàn)闀?huì)把系統(tǒng)的功能給覆蓋掉,而且分類中不能調(diào)用super.
// 既能加載圖片又能打印
+(instancetype)imageWithName:(NSString *)name
{
// 這里調(diào)用imageWithName税灌,相當(dāng)于調(diào)用imageName
UIImage *image = [self imageWithName:name];
if (image == nil) {
NSLog(@"加載空的圖片");
}
return image;
}

2.動(dòng)態(tài)添加方法

  • 開(kāi)發(fā)使用場(chǎng)景:加載類到內(nèi)存的時(shí)候也比較耗費(fèi)資源均函,需要給每個(gè)方法生成映射表,可以使用動(dòng)態(tài)給某個(gè)類菱涤,添加方法解決苞也。(經(jīng)典面試題:有沒(méi)有使用performSelector,其實(shí)主要想問(wèn)你有沒(méi)有動(dòng)態(tài)添加過(guò)方法粘秆。)

@implementation ViewController

  • (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    Person *p = [[Person alloc] init];
    // 默認(rèn)person如迟,沒(méi)有實(shí)現(xiàn)eat方法,可以通過(guò)performSelector調(diào)用攻走,但是會(huì)報(bào)錯(cuò)殷勘。
    // 動(dòng)態(tài)添加方法就不會(huì)報(bào)錯(cuò)
    [p performSelector:@selector(eat)];
    }
    @end

@implementation Person
// void(*)()
// 默認(rèn)方法都有兩個(gè)隱式參數(shù),
void eat(id self,SEL sel)
{
NSLog(@"%@ %@",self,NSStringFromSelector(sel));
}
// 當(dāng)一個(gè)對(duì)象調(diào)用未實(shí)現(xiàn)的方法昔搂,會(huì)調(diào)用這個(gè)方法處理,并且會(huì)把對(duì)應(yīng)的方法列表傳過(guò)來(lái).
// 剛好可以用來(lái)判斷玲销,未實(shí)現(xiàn)的方法是不是我們想要?jiǎng)討B(tài)添加的方法
+(BOOL)resolveInstanceMethod:(SEL)sel
{
if (sel == @selector(eat)) {
// 動(dòng)態(tài)添加eat方法
// 第一個(gè)參數(shù):給哪個(gè)類添加方法
// 第二個(gè)參數(shù):添加方法的方法編號(hào)
// 第三個(gè)參數(shù):添加方法的函數(shù)實(shí)現(xiàn)(函數(shù)地址)
// 第四個(gè)參數(shù):函數(shù)的類型,(返回值+參數(shù)類型) v:void @:對(duì)象->self :表示SEL->_cmd
class_addMethod(self, @selector(eat), eat, "v@:");
}
return [super resolveInstanceMethod:sel];
}
@end

3.給分類添加屬性

  • 原理:給一個(gè)類聲明屬性巩趁,其實(shí)本質(zhì)就是給這個(gè)類添加關(guān)聯(lián)痒玩,并不是直接把這個(gè)值的內(nèi)存空間添加到類存空間淳附。

@implementation ViewController
-(void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// 給系統(tǒng)NSObject類動(dòng)態(tài)添加屬性name
NSObject *objc = [[NSObject alloc] init];
objc.name = @"小碼哥";

NSLog(@"%@",objc.name);

}
@end


// 定義關(guān)聯(lián)的key
static const char *key = "name";
@implementation NSObject (Property)

  • (NSString *)name
    {
    // 根據(jù)關(guān)聯(lián)的key议慰,獲取關(guān)聯(lián)的值。
    return objc_getAssociatedObject(self, key);
    }
  • (void)setName:(NSString *)name
    {
    // 第一個(gè)參數(shù):給哪個(gè)對(duì)象添加關(guān)聯(lián)
    // 第二個(gè)參數(shù):關(guān)聯(lián)的key奴曙,通過(guò)這個(gè)key獲取
    // 第三個(gè)參數(shù):關(guān)聯(lián)的value
    // 第四個(gè)參數(shù):關(guān)聯(lián)的策略
    objc_setAssociatedObject(self,key,name,OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    @end

4.字典轉(zhuǎn)模型

  • 自動(dòng)根據(jù)一個(gè)字典别凹,生成對(duì)應(yīng)的屬性,和字典中的key一一對(duì)應(yīng)洽糟。

@implementation NSObject (Log)
// 自動(dòng)打印屬性字符串
+(void)resolveDict:(NSDictionary *)dict{
// 拼接屬性字符串代碼
NSMutableString *strM = [NSMutableString string];
// 1.遍歷字典炉菲,把字典中的所有key取出來(lái)堕战,生成對(duì)應(yīng)的屬性代碼
[dict enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
//類型經(jīng)常變,抽出來(lái)
NSString *type;
if ([obj isKindOfClass:NSClassFromString(@"__NSCFString")]) {
type = @"NSString";
}else if ([obj isKindOfClass:NSClassFromString(@"__NSCFArray")]){
type = @"NSArray";
}else if ([obj isKindOfClass:NSClassFromString(@"__NSCFNumber")]){
type = @"int";
}else if ([obj isKindOfClass:NSClassFromString(@"__NSCFDictionary")]){
type = @"NSDictionary";
}
// 屬性字符串
NSString *str;
if ([type containsString:@"NS"]) {
str = [NSString stringWithFormat:@"@property (nonatomic, strong) %@ *%@;",type,key];
}else{
str = [NSString stringWithFormat:@"@property (nonatomic, assign) %@ %@;",type,key];
}
// 每生成屬性字符串拍霜,就自動(dòng)換行嘱丢。
[strM appendFormat:@"\n%@\n",str];
}];
// 把拼接好的字符串打印出來(lái),就好了祠饺。
NSLog(@"%@",strM);
}
@end

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末越驻,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子道偷,更是在濱河造成了極大的恐慌缀旁,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,576評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件勺鸦,死亡現(xiàn)場(chǎng)離奇詭異并巍,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)换途,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門懊渡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人军拟,你說(shuō)我怎么就攤上這事距贷。” “怎么了吻谋?”我有些...
    開(kāi)封第一講書人閱讀 168,017評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵忠蝗,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我漓拾,道長(zhǎng)阁最,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 59,626評(píng)論 1 296
  • 正文 為了忘掉前任骇两,我火速辦了婚禮速种,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘低千。我一直安慰自己配阵,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,625評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布示血。 她就那樣靜靜地躺著棋傍,像睡著了一般。 火紅的嫁衣襯著肌膚如雪难审。 梳的紋絲不亂的頭發(fā)上瘫拣,一...
    開(kāi)封第一講書人閱讀 52,255評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音告喊,去河邊找鬼麸拄。 笑死派昧,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的拢切。 我是一名探鬼主播蒂萎,決...
    沈念sama閱讀 40,825評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼淮椰!你這毒婦竟也來(lái)了岖是?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,729評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤实苞,失蹤者是張志新(化名)和其女友劉穎豺撑,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體黔牵,經(jīng)...
    沈念sama閱讀 46,271評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡聪轿,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,363評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了猾浦。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片陆错。...
    茶點(diǎn)故事閱讀 40,498評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖金赦,靈堂內(nèi)的尸體忽然破棺而出音瓷,到底是詐尸還是另有隱情,我是刑警寧澤夹抗,帶...
    沈念sama閱讀 36,183評(píng)論 5 350
  • 正文 年R本政府宣布绳慎,位于F島的核電站,受9級(jí)特大地震影響漠烧,放射性物質(zhì)發(fā)生泄漏杏愤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,867評(píng)論 3 333
  • 文/蒙蒙 一已脓、第九天 我趴在偏房一處隱蔽的房頂上張望珊楼。 院中可真熱鬧,春花似錦度液、人聲如沸厕宗。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,338評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)已慢。三九已至,卻和暖如春照宝,著一層夾襖步出監(jiān)牢的瞬間蛇受,已是汗流浹背句葵。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,458評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工厕鹃, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留兢仰,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,906評(píng)論 3 376
  • 正文 我出身青樓剂碴,卻偏偏與公主長(zhǎng)得像把将,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子忆矛,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,507評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉察蹲,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,725評(píng)論 0 9
  • RunTime簡(jiǎn)稱運(yùn)行時(shí)。OC就是運(yùn)行時(shí)機(jī)制催训,也就是在運(yùn)行時(shí)候的一些機(jī)制洽议,其中最主要的是消息機(jī)制。對(duì)于C語(yǔ)言漫拭,函數(shù)...
    _心暖閱讀 544評(píng)論 1 1
  • 1. runtime的簡(jiǎn)介runtime是一套比較底層的純C語(yǔ)言API, 屬于1個(gè)C語(yǔ)言庫(kù), 包含了很多底層的C語(yǔ)...
    凸阿濱閱讀 320評(píng)論 0 0
  • 01 省廳小組要來(lái) 到了新崗位采驻,接到一個(gè)“大任務(wù)”审胚,公司業(yè)務(wù)方面有一個(gè)證件有效期要到了,需要申請(qǐng)延續(xù)礼旅。 看著很簡(jiǎn)單...
    職場(chǎng)解憂君閱讀 307評(píng)論 0 2
  • 我們不用把很多事情做的牛逼膳叨。 今天和朋友分享我覺(jué)得自我成長(zhǎng)后,我在事業(yè)心態(tài)上最大的改變痘系,就是我站著可以眼前友菲嘴,體力...
    體面事物所的紀(jì)先生閱讀 198評(píng)論 0 0