iOS | 面試基礎(chǔ)整理 OC底層 (三)

iOS | 面試知識整理 - OC底層 (三)

1. 一個OC對象占用多少內(nèi)存

系統(tǒng)分配了16個字節(jié)給NSObject對象(通過malloc_size函數(shù)獲得)

但NSObject對象內(nèi)部只使用了8個字節(jié)的空間(64bit環(huán)境下,可以通過class_getInstanceSize函數(shù)獲得)

2. 對象的isa指針指向哪里聋涨?

instance對象的isa指向class對象

class對象的isa指向meta-class對象

meta-class對象的isa指向基類的meta-class對象

3.OC的類信息存放在哪里?

對象方法、屬性、成員變量瞒爬、協(xié)議信息,存放在class對象中

類方法沟堡,存放在meta-class對象中

成員變量的具體值侧但,存放在instance對象

4.iOS用什么方式實現(xiàn)對一個對象的KVO?(KVO的本質(zhì)是什么航罗?)

利用RuntimeAPI動態(tài)生成一個子類禀横,并且讓instance對象的isa指向這個全新的子類

當(dāng)修改instance對象的屬性時,會調(diào)用Foundation的_NSSetXXXValueAndNotify函數(shù)

willChangeValueForKey:

父類原來的setter

didChangeValueForKey:

內(nèi)部會觸發(fā)監(jiān)聽器(Oberser)的監(jiān)聽方法(observeValueForKeyPath:ofObject:change:context:)

5.如何手動觸發(fā)KVO粥血?

手動調(diào)用willChangeValueForKey:和didChangeValueForKey:

- (void)viewDidLoad {[superviewDidLoad];? ? ? ? Person *person = [[Person alloc]init];;? ? [p addObserver:selfforKeyPath:@"name"options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOldcontext:nil];? ? [p willChangeValueForKey:@"name"];? ? [p didChangeValueForKey:@"name"];}-(void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void*)context{NSLog(@"被觀測對象:%@, 被觀測的屬性:%@, 值的改變: %@\n, 攜帶信息:%@", object, keyPath, change, context);}

6.直接修改成員變量會觸發(fā)KVO么柏锄?

不會觸發(fā)KVO

7.通過KVC修改屬性會觸發(fā)KVO么?

會觸發(fā)KVO

KVC在賦值時候,內(nèi)部會觸發(fā)監(jiān)聽器(Oberser)的監(jiān)聽方法(observeValueForKeyPath:ofObject:change:context:) 發(fā)送通知

8.KVC的賦值和取值過程是怎樣的复亏?原理是什么趾娃?

KVC的全稱是Key-Value Coding,俗稱“鍵值編碼”缔御,可以通過一個key來訪問某個屬性

調(diào)用 setValue:forKey:

setKey,_setKey? ->找到了則進行賦值,未找到調(diào)用accessInstanceVarlableDirctly是否允許修改value值,返回YES, 調(diào)用_key, _isKey, key, isKey 進行賦值

9.Category的使用場合是什么抬闷?

在不修改原有類代碼的情況下,為類添對象方法或者類方法

或者為類關(guān)聯(lián)新的屬性

分解龐大的類文件

使用場合:

添加實例方法

添加類方法

添加協(xié)議

添加屬性

關(guān)聯(lián)成員變量

10.Category的實現(xiàn)原理

Category編譯之后的底層結(jié)構(gòu)是struct category_t,里面存儲著分類的對象方法刹淌、類方法饶氏、屬性、協(xié)議信息

在程序運行的時候有勾,runtime會將Category的數(shù)據(jù)疹启,合并到類信息中(類對象、元類對象中)

11.Category和Class Extension的區(qū)別是什么蔼卡?

Class Extension在編譯的時候喊崖,它的數(shù)據(jù)就已經(jīng)包含在類信息中

Category是在運行時挣磨,才會將數(shù)據(jù)合并到類信息中

12.Category中有l(wèi)oad方法嗎?load方法是什么時候調(diào)用的荤懂?load 方法能繼承嗎茁裙?

有l(wèi)oad方法

load方法在runtime加載類、分類的時候調(diào)用

load方法可以繼承节仿,但是一般情況下不會主動去調(diào)用load方法晤锥,都是讓系統(tǒng)自動調(diào)用

13. initialize方法如何調(diào)用,以及調(diào)用時機

當(dāng)類第一次收到消息的時候會調(diào)用類的initialize方法

是通過 runtime 的消息機制 objc_msgSend(obj,@selector()) 進行調(diào)用的

優(yōu)先調(diào)用分類的 initialize, 如果沒有分類會調(diào)用 子類的,如果子類未實現(xiàn)則調(diào)用 父類的

13. load休吠、initialize方法的區(qū)別什么浑厚?它們在category中的調(diào)用的順序?以及出現(xiàn)繼承時他們之間的調(diào)用過程巧婶?

load 是類加載到內(nèi)存時候調(diào)用, 優(yōu)先父類->子類->分類

initialize 是類第一次收到消息時候調(diào)用,優(yōu)先分類->子類->父類

同級別和編譯順序有關(guān)系

load 方法是在 main 函數(shù)之前調(diào)用的

14. Category能否添加成員變量箭启?如果可以壕翩,如何給Category添加成員變量?

不能直接給Category添加成員變量傅寡,但是可以間接實現(xiàn)Category有成員變量的效果

Category是發(fā)生在運行時,編譯完畢,類的內(nèi)存布局已經(jīng)確定,無法添加成員變量(Category的底層數(shù)據(jù)結(jié)構(gòu)也沒有成員變量的結(jié)構(gòu))

可以通過 runtime 動態(tài)的關(guān)聯(lián)屬性

15. block的原理是怎樣的放妈?本質(zhì)是什么?

block 本質(zhì)其實是OC對象

block 內(nèi)部封裝了函數(shù)調(diào)用以及調(diào)用環(huán)境

16. __block的作用是什么荐操?有什么使用注意點芜抒?

如果需要在 block 內(nèi)部修改外部的 局部變量的值,就需要使用__block 修飾(全局變量和靜態(tài)變量不需要加__block 可以修改)

__block 修飾以后,局部變量的數(shù)據(jù)結(jié)構(gòu)就會發(fā)生改變,底層會變成一個結(jié)構(gòu)體的對象,結(jié)構(gòu)內(nèi)部會聲明 一個 __block修飾變量的成員, 并且將 __block修飾變量的地址保存到堆內(nèi)存中. 后面如果修改 這個變量的值,可以通過 isa 指針找到這個結(jié)構(gòu)體,進來修改 這個變量的值;

可以在 block 內(nèi)部修改 變量的值

17. block的屬性修飾詞為什么是copy?使用block有哪些使用注意淀零?

block 一旦沒有進行copy操作挽绩,就不會在堆上

使用注意:循環(huán)引用問題 (外部使用__weak 解決)

17. block在修改NSMutableArray膛壹,需不需要添加__block驾中?

如果是操作 NSMutableArray 對象不需要,因為 block 內(nèi)部拷貝了 NSMutableArray對象的內(nèi)存地址,實際是通過內(nèi)存地址操作的

如果 NSMutableArray 對象要重新賦值,就需要加__block

18. Block 內(nèi)部為什么不能修改局部變量,需要加__block

通過查看Block 源碼,可以發(fā)現(xiàn), block 內(nèi)部如果單純使用 外部變量, 會在 block 內(nèi)部創(chuàng)建同樣的一個變量,并且將 外部變量的值引用過來..(只是將外部變量值拷貝到 block 內(nèi)部), 內(nèi)部這個變量和外部 實際已經(jīng)沒關(guān)系了

從另一方面分析,block 本質(zhì)也是一個 函數(shù)指針, 外部的變量也是一個局部變量,很有可能 block 在使用這個變量時候,外部變量已經(jīng)釋放了,會造成錯誤

加了__block 以后, 會將外部變量的內(nèi)存拷貝到堆中, 內(nèi)存由 block 去管理.

19.講一下 OC 的消息機制

OC中的方法調(diào)用其實都是轉(zhuǎn)成了objc_msgSend函數(shù)的調(diào)用,給receiver(方法調(diào)用者)發(fā)送了一條消息(selector方法名)

objc_msgSend底層有3大階段

消息發(fā)送(當(dāng)前類模聋、父類中查找)肩民、

動態(tài)方法解析、

消息轉(zhuǎn)發(fā)

20. 消息發(fā)送流程

當(dāng)我們的一個 receiver(實例對象)收到消息的時候, 會通過 isa 指針找到 他的類對象, 然后在類對象方法列表中查找 對應(yīng)的方法實現(xiàn),如果 未找到,則會通過 superClass 指針找到其父類的類對象, 找到則返回,未找打則會一級一級往上查到,最終到NSObject 對象, 如果還是未找到就會進行動態(tài)方法解析

類方法調(diào)用同上,只不過 isa 指針找到元類對象;

21. 動態(tài)方法解析機制

當(dāng)我們發(fā)送消息未找到方法實現(xiàn),就會進入第二步,動態(tài)方法解析: 代碼實現(xiàn)如下

//? 動態(tài)方法綁定- 實例法法調(diào)用+ (BOOL)resolveInstanceMethod:(SEL)sel{if(sel ==@selector(run)) {? ? ? ? Method method = class_getInstanceMethod(self,@selector(test));? ? ? ? class_addMethod(self, sel, method_getImplementation(method), method_getTypeEncoding(method));returnYES;? ? }return[superresolveInstanceMethod:sel];}// 類方法調(diào)用+(BOOL) resolveClassMethod:(SEL)sel....

22.消息轉(zhuǎn)發(fā)機制流程

未找到動態(tài)方法綁定,就會進行消息轉(zhuǎn)發(fā)階段

// 快速消息轉(zhuǎn)發(fā)- 指定消息處理對象- (id)forwardingTargetForSelector:(SEL)aSelector{if(aSelector ==@selector(run)) {return[Student new];? ? }return[superforwardingTargetForSelector:aSelector];}// 標(biāo)準(zhǔn)消息轉(zhuǎn)發(fā)-消息簽名- (NSMethodSignature*)methodSignatureForSelector:(SEL)aSelector{if(aSelector ==@selector(run))? ? {return[NSMethodSignaturesignatureWithObjCTypes:"v@:"];? ? }return[supermethodSignatureForSelector:aSelector];}- (void)forwardInvocation:(NSInvocation*)anInvocation{//內(nèi)部邏輯自己處理 }

23. 什么是Runtime链方?平時項目中有用過么持痰?

Objective-C runtime是一個運行時庫,它為Objective-C語言的動態(tài)特性提供支持祟蚀,我們所寫的OC代碼在運行時都轉(zhuǎn)成了runtime相關(guān)的代碼工窍,類轉(zhuǎn)換成C語言對應(yīng)的結(jié)構(gòu)體,方法轉(zhuǎn)化為C語言對應(yīng)的函數(shù)前酿,發(fā)消息轉(zhuǎn)成了C語言對應(yīng)的函數(shù)調(diào)用患雏。通過了解runtime以及源碼,可以更加深入的了解OC其特性和原理

OC是一門動態(tài)性比較強的編程語言,允許很多操作推遲到程序運行時再進行

OC的動態(tài)性就是由Runtime來支撐和實現(xiàn)的罢维,Runtime是一套C語言的API淹仑,封裝了很多動態(tài)性相關(guān)的函數(shù)

平時編寫的OC代碼,底層都是轉(zhuǎn)換成了Runtime API進行調(diào)用

22.runtime具體應(yīng)用

利用關(guān)聯(lián)對象(AssociatedObject)給分類添加屬性

遍歷類的所有成員變量(修改textfield的占位文字顏色、字典轉(zhuǎn)模型匀借、自動歸檔解檔)

交換方法實現(xiàn)(交換系統(tǒng)的方法)

利用消息轉(zhuǎn)發(fā)機制解決方法找不到的異常問題

23.unrecognized selector sent to instance 錯誤

該錯誤是基于OC的消息機制:

在方法列表中未找到方法實現(xiàn)

嘗試動態(tài)方法解析,也未綁定犯法

進行消息轉(zhuǎn)發(fā),也未處理

最后進行報錯

24.如果向一個nil對象發(fā)消息不會crash的話,那么message sent to deallocated instance的錯誤是怎么回事颜阐?

這是因為這個對象已經(jīng)被釋放了(引用計數(shù)為0了),那么這個時候再去調(diào)用方法肯定是會Crash的吓肋,因為這個時候這個對象就是一個野指針(指向僵尸對象(對象的引用計數(shù)為0凳怨,指針指向的內(nèi)存已經(jīng)不可用)的指針)了,安全的做法是釋放后將對象重新置為nil是鬼,使它成為一個空指針

25. 向一個nill對象發(fā)送消息會發(fā)生什么猿棉?

OC中向nil發(fā)消息,什么都不會方式,程序是不會崩潰的屑咳。

因為OC的函數(shù)都是通過objc_msgSend進行消息發(fā)送來實現(xiàn)的萨赁,相對于C和C++來說,對于空指針的操作會引起crash問題兆龙,而objc_msgSend會通過判斷self來決定是否發(fā)送消息杖爽,如果self為nil,那么selector也會為空紫皇,直接返回慰安,不會出現(xiàn)問題。視方法返回值聪铺,向nil發(fā)消息可能會返回nil(返回值為對象)化焕,0(返回值為一些基礎(chǔ)數(shù)據(jù))或0X0(返回值為id)等。但對于[NSNull null]對象發(fā)送消息時铃剔,是會crash的撒桨,因為NSNull類只有一個null方法

26.代碼打印結(jié)果:

@interfacePerson:NSObject@end@implementationPerson@end@interfaceStudent:Person@end@implementationStudent- (instancetype)init{if(self= [superinit]) {NSLog(@"%@", [selfclass]);NSLog(@"%@", [superclass]);NSLog(@"%@", [selfsuperclass]);NSLog(@"%@", [supersuperclass]);? ? }}[selfclass] 和 [superclass] 都是給當(dāng)前類返送消息,spuer 表示在父類中查找[selfsuperClass]? 和 [supersuperclass] 也是也當(dāng)前類發(fā)消息,返回父類第一個打印:Student / Student/ Person / Person

27.代碼運行結(jié)果?

BOOLres1 = [[NSObjectclass] isKindOfClass:[NSObjectclass]];BOOLres2 = [[NSObjectclass] isMemberOfClass:[NSObjectclass]];BOOLres3 = [[Personclass] isKindOfClass:[Personclass]];BOOLres4 = [[Personclass] isMemberOfClass:[Personclass]];NSLog(@"%d-%d-%d-%d",res1, res2, res3, res4);

isKindOfClass 表示對象是否為當(dāng)前類或者子類的 類型

isMemberOfClass 表示是否為當(dāng)前類的的類型

isMemberOfClass 分為- 對象方法 和+ 類方法2中

- (bool)isMemberOfClass; 比較的是類對象

+ (bool)isMemberOfClass; 比較的是元類

打印結(jié)果: 1 ,0, 0, 0

28.講講 RunLoop,項目中有用到嗎键兜?

runloop運行循環(huán),保證程序一直運行,主線程默認開啟

用于處理線程上的各種事件,定時器等

可以提高程序性能,節(jié)約CPU資源,有事情做就做,沒事情做就讓線程休眠

應(yīng)用范疇:

定時器,事件響應(yīng),手勢識別,界面刷新,以及autoreleasePool 等等

29.runloop內(nèi)部實現(xiàn)邏輯凤类?

實際上 RunLoop 就是這樣一個函數(shù),其內(nèi)部是一個 do-while 循環(huán)普气。當(dāng)你調(diào)用 CFRunLoopRun() 時谜疤,線程就會一直停留在這個循環(huán)里;直到超時或被手動停止现诀,該函數(shù)才會返回夷磕。

30.runloop和線程的關(guān)系?

每條線程都有唯一的一個與之對應(yīng)的RunLoop對象

RunLoop保存在一個全局的Dictionary里仔沿,線程作為key坐桩,RunLoop作為value

線程剛創(chuàng)建時并沒有RunLoop對象,RunLoop會在第一次獲取它時創(chuàng)建

RunLoop會在線程結(jié)束時銷毀

主線程的RunLoop已經(jīng)自動獲扔谖础(創(chuàng)建)撕攒,子線程默認沒有開啟RunLoop

31.timer 與 runloop 的關(guān)系陡鹃?

timer 定時器,是基于 runloop 來實現(xiàn)的, runloop 在運行循環(huán)當(dāng)中,監(jiān)聽到了定制器 就會執(zhí)行;所以 timer 需要添加到 runloop 中去, 注意子線程的 runloop 默認是不開啟的,如果在子線程執(zhí)行 timer 需要手動開啟 runloop

32.程序中添加每3秒響應(yīng)一次的NSTimer,當(dāng)拖動tableview時timer可能無法響應(yīng)要怎么解決抖坪?

將 timer 對象添加到 runloop 中,并修改 runloop 的運行 mode

NSTimer*timer = [NSTimertimerWithTimeInterval:1repeats:YESblock:nil]; [[NSRunLoopcurrentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

33. runloop的mode作用是什么萍鲸?

runloop 只能在一種 mode 下運行, 做不同的事情,runloop 會切換到對應(yīng)的 model 下來執(zhí)行,默認是? kCFRunLoopDefaultMode 如果視圖滑動再回切換到? UITrackingRunLoopMode,如果需要在多種 mode 下運行則需要手動設(shè)置 kCFRunLoopCommonModes;

kCFRunLoopDefaultMode:App的默認Mode,通常主線程是在這個Mode下運行

UITrackingRunLoopMode:界面跟蹤 Mode擦俐,用于 ScrollView 追蹤觸摸滑動脊阴,保證界面滑動時不受其他 Mode 影響

UIInitializationRunLoopMode: 在剛啟動 App 時第進入的第一個 Mode,啟動完成后就不再使用蚯瞧,會切換到kCFRunLoopDefaultMode

GSEventReceiveRunLoopMode: 接受系統(tǒng)事件的內(nèi)部 Mode嘿期,通常用不到

kCFRunLoopCommonModes: 這是一個占位用的Mode,作為標(biāo)記kCFRunLoopDefaultMode和UITrackingRunLoopMode用埋合,并不是一種真正的Mode

34.使用method swizzling要注意什么?

方式無限循環(huán)

進行版本迭代的時候需要進行一些檢驗备徐,防止系統(tǒng)庫的函數(shù)發(fā)生了變化

35. 一個系統(tǒng)方法被 多次交換,會有什么影響嗎?以及調(diào)用順序?原理

都會執(zhí)行,后交換的會先調(diào)用.


第一次交換? viewwillAppAppear 和 test1 的指向的方法實現(xiàn)地址發(fā)生變化

第二次交換? viewwillAppAppear 和 test2 實際上等于是 test2 和 test1 進行了交換,因為 viewwillAppAppear 已經(jīng)變?yōu)榱?test1了.

調(diào)用 --> viewwillAppAppear

實際調(diào)用順序 -->test2--->test1-->viewwillAppAppear

形成一個閉環(huán):viewwillAppAppear 也只會調(diào)用一次

36.runloop 主線程監(jiān)聽卡頓

用戶層面感知的卡頓都是來自處理所有UI的主線程上,包括在主線程上進行的大計算甚颂,大量的IO操作蜜猾,或者比較重的繪制工作。

如何監(jiān)控主線程呢振诬,首先需要知道的是主線程和其它線程一樣都是靠NSRunLoop來驅(qū)動的蹭睡。可以先看看CFRunLoopRun的大概的邏輯 ,不難發(fā)現(xiàn)NSRunLoop調(diào)用方法主要就是在kCFRunLoopBeforeSources和kCFRunLoopBeforeWaiting之間,還有kCFRunLoopAfterWaiting之后,也就是如果我們發(fā)現(xiàn)這兩個時間內(nèi)耗時太長,那么就可以判定出此時主線程卡頓.只需要另外再開啟一個線程,實時計算這兩個狀態(tài)區(qū)域之間的耗時是否到達某個閥值,便能揪出這些性能殺手.

用GCD里的dispatch_semaphore_t開啟一個新線程赶么,設(shè)置一個極限值和出現(xiàn)次數(shù)的值肩豁,然后獲取主線程上在kCFRunLoopBeforeSources到kCFRunLoopBeforeWaiting再到kCFRunLoopAfterWaiting兩個狀態(tài)之間的超過了極限值和出現(xiàn)次數(shù)的場景,將堆棧dump下來辫呻,最后發(fā)到服務(wù)器做收集清钥,通過堆棧能夠找到對應(yīng)出問題的那個方法。

- (void)start{if(observer)return;// // 創(chuàng)建信號semaphore = dispatch_semaphore_create(0);// 注冊RunLoop狀態(tài)觀察CFRunLoopObserverContextcontext = {0,(__bridgevoid*)self,NULL,NULL};? ? observer =CFRunLoopObserverCreate(kCFAllocatorDefault,? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? kCFRunLoopAllActivities,YES,0,? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &runLoopObserverCallBack,? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &context);CFRunLoopAddObserver(CFRunLoopGetMain(), observer, kCFRunLoopCommonModes);// 在子線程監(jiān)控時長dispatch_async(dispatch_get_global_queue(0,0), ^{while(YES)? ? ? ? {// 假定連續(xù)5次超時50ms認為卡頓(當(dāng)然也包含了單次超時250ms)longst = dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW,50*NSEC_PER_MSEC));// Returns zero on success, or non-zero if the timeout occurred.if(st !=0)? ? ? ? ? ? {if(!observer)? ? ? ? ? ? ? ? {? ? ? ? ? ? ? ? ? ? timeoutCount =0;? ? ? ? ? ? ? ? ? ? semaphore =0;? ? ? ? ? ? ? ? ? ? activity =0;return;? ? ? ? ? ? ? ? }// kCFRunLoopBeforeSources 即將處理source kCFRunLoopAfterWaiting 剛從睡眠中喚醒// RunLoop會一直循環(huán)檢測印屁,從線程start到線程end循捺,檢測檢測到事件源(CFRunLoopSourceRef)執(zhí)行處理函數(shù)斩例,首先會產(chǎn)生通知雄人,corefunction向線程添加runloopObservers來監(jiān)聽事件,并控制NSRunLoop里面線程的執(zhí)行和休眠念赶,在有事情做的時候使當(dāng)前NSRunLoop控制的線程工作础钠,沒有事情做讓當(dāng)前NSRunLoop的控制的線程休眠。if(activity == kCFRunLoopBeforeSources || activity == kCFRunLoopAfterWaiting)? ? ? ? ? ? ? ? {if(++timeoutCount <3)continue;NSLog(@"有點兒卡");? ? ? ? ? ? ? ? }? ? ? ? ? ? }? ? ? ? ? ? timeoutCount =0;? ? ? ? }? ? });}

37. _objc_msgForward 函數(shù)是做什么的?直接 調(diào)用它將會發(fā)生什么?

_objc_msgForward 是 IMP 類型叉谜,用于消息轉(zhuǎn)發(fā)的:當(dāng)向一個對象發(fā)送一條消息旗吁,但 它并沒有實現(xiàn)的時候,_objc_msgForward 會嘗試做消息轉(zhuǎn)發(fā)

直接調(diào)用_objc_msgForward 是非常危險的事停局,這是把雙刃刀很钓,如果用不好會直接 導(dǎo)致程序 Crash香府,但是如果用得好,能做很多非陈刖耄酷的事

JSPatch 就是直接調(diào)用_objc_msgForward 來實現(xiàn)其核心功能的

38. 如何打印一個類中的所有實例變量

OC的類實際上是一個objc_class類型的結(jié)構(gòu)體,包含了實例變量列表: (objc_ivar_list),可以通過 runtime 函數(shù)來獲取這個列表:

OBJC_EXPORT Ivar _Nonnull * _Nullable class_copyIvarList(Class _Nullable cls, unsigned int * _Nullable outCount)

例子:

Student *stu = [[Student alloc]init];stu.stu_name =@"alex";stu.stu_age =10;unsignedintcount =0;Ivar *list = class_copyIvarList([stuclass], &count);NSMutableDictionary* dict = [NSMutableDictionarydictionary];for(inti =0; i< count; i++){idiVarName = [NSStringstringWithUTF8String:ivar_getName(list[i])];? ? dict[iVarName] = [stu valueForKey:iVarName];}NSLog(@"%@",dict);

39. 如何使用 rumtime 動態(tài)添加一個類

runtime 很強大.可以動態(tài)的創(chuàng)建一個全新的類或?qū)ο?/p>

// 添加一個繼承NSObject的類 類名是MyClassClass MyClass = objc_allocateClassPair([NSObjectclass],"MyClass",0);// 增加實例變量class_addIvar(MyClass,"_age",sizeof(NSString*),0,"@");//注冊這個類到runtime系統(tǒng)中就可以使用他了objc_registerClassPair(MyClass);//生成了一個實例化對象idmyobj = [[MyClass alloc] init];//給剛剛添加的變量賦值[myobj setValue:@30forKey:@"age"];// 打印NSLog(@"age= %@",[myobj valueForKey:@"age"]);

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末企孩,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子袁稽,更是在濱河造成了極大的恐慌勿璃,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件推汽,死亡現(xiàn)場離奇詭異补疑,居然都是意外死亡,警方通過查閱死者的電腦和手機歹撒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進店門莲组,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人暖夭,你說我怎么就攤上這事胁编。” “怎么了鳞尔?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵嬉橙,是天一觀的道長。 經(jīng)常有香客問我寥假,道長市框,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任糕韧,我火速辦了婚禮枫振,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘萤彩。我一直安慰自己粪滤,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布雀扶。 她就那樣靜靜地躺著杖小,像睡著了一般。 火紅的嫁衣襯著肌膚如雪愚墓。 梳的紋絲不亂的頭發(fā)上予权,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天,我揣著相機與錄音浪册,去河邊找鬼扫腺。 笑死,一個胖子當(dāng)著我的面吹牛村象,可吹牛的內(nèi)容都是我干的笆环。 我是一名探鬼主播攒至,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼躁劣!你這毒婦竟也來了嗓袱?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤习绢,失蹤者是張志新(化名)和其女友劉穎渠抹,沒想到半個月后闪萄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體败去,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡放航,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年广鳍,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吓妆。...
    茶點故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡行拢,死狀恐怖舟奠,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情沼瘫,我是刑警寧澤耿戚,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布晓锻,位于F島的核電站,受9級特大地震影響屑墨,放射性物質(zhì)發(fā)生泄漏卵史。R本人自食惡果不足惜战转,卻給世界環(huán)境...
    茶點故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望刁标。 院中可真熱鬧址晕,春花似錦谨垃、人聲如沸刘陶。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽乡小。三九已至满钟,卻和暖如春湃番,著一層夾襖步出監(jiān)牢的瞬間吭露,已是汗流浹背讲竿。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工鞋诗, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留削彬,地道東北人融痛。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓拌消,卻偏偏與公主長得像墩崩,于是被迫代替她去往敵國和親鹦筹。 傳聞我的和親對象是個殘疾皇子铐拐,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,675評論 2 359

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