iOS類新增方法、屬性學習筆記
一、在執行時為類新增方法
我們首先定義了一個EmptyClass,繼承NSObject,沒有任何自帶方法,接著定義了一個函式。這裡提一句,Obj-C的方法(method)就是一個至少需要兩個引數(self,_cmd)的C函式,這個函式僅僅輸出一句Hello。接下來在addMethod方法中,我們呼叫class_addMethod()為EmptyClass新增方法,class_addMethod()是這樣定義的:
BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types)
引數說明:
cls:被新增方法的類。
name:可以理解為方法名,這個貌似隨便起名,比如我們這裡叫sayHello2。
imp:實現這個方法的函式。
types:一個定義該函式返回值型別和引數型別的字串。
接著建立EmptyClass的例項,呼叫sayHello2,執行,輸出Hello,新增方法成功。
#if TARGET_IPHONE_SIMULATOR
#import <objc/objc-runtime.h>
#else
#import <objc/runtime.h>
#import <objc/message.h>
#endif
@interface EmptyClass:NSObject
@end
@implementation EmptyClass
@end
void sayHello(id self, SEL _cmd) {
NSLog(@"Hello");
}
- (void)addMethod {
class_addMethod([EmptyClass class], @selector(sayHello2), (IMP)sayHello, "v@:");
// Test Method
EmptyClass *instance = [[EmptyClass alloc] init];
[instance sayHello2];
[instance release];
}
二、為什麼不要重寫原有類方法
主要原因如下:
CocoaFramework有很多是用Category實現的,重寫之後,會導致在Runtime的時 候,只有一個方法會被執行,而哪個會被執行是undefined。
例如,重寫NSString的一個方法base64EncodedString,而其他CocoaFramework的也有可能使用Category來實現這個方法,這樣就會導致在Runtime的時候,執行哪個方法是Undefined。
另外,有個地方要注意,那就是Category方法的命名。
通常的明明方式是加一個字首,例如
-(void)WC_setUpCustomButton;
因為,現在名字並未發生衝突,IOS版本在更新,SDK也在更新,也就是說要儘量保證將來方法的名稱也不發生衝突。
三、聯合儲存實現方式及底層原理解析
動態語言的最大好處,就是靈活性,對於Objective-C來說,能在執行時動態地為類增加方法和例項變數是很多其它語言羨慕不已的能力。現在說說為類增加例項變數用到的技術:聯合儲存。
一、聯合儲存的實現方式
下面這段程式碼實現了為Duck類增加color屬性:
Duck+associative.h檔案
#import "Duck.h"
@interface Duck (associative)
@property (nonatomic, retain) NSString *color;
@end
Duck+associative.m檔案
#import "Duck+associative.h"
#import <objc/runtime.h>
@implementation Duck (associative)
static char colorKey = NULL;
- (NSString *)color {
return objc_getAssociatedObject(self, &colorKey);
}
- (void)setColor:(NSString *)aColor {
objc_setAssociatedObject(self, &colorKey,
aColor,
OBJC_ASSOCIATION_RETAIN);
}
呼叫舉例:
Duck *smallDuck = [[Duck alloc] init];
smallDuck.color = @"red color";
NSLog(@"duck color:%@",smallDuck.color);
[smallDuck release];
輸出結果:
2013-07-18 19:09:26.578 ObjcRunTime[429:403] duck color:red color
至此,我們已經成功的為Duck類增加了一個color屬性。
四、聯合儲存的優缺點
1、優點
聯合儲存的最大的優點,在於它能通過靈活的方式實現為類增加屬性。
2、缺點
效率低,使用單條機器指令就可以訪問真正的例項變數,但是訪問儲存在對映表中的值需要多個函式呼叫,效率問題還是需要注意的。
事實上,目前許多Cocoa類,像NSAttributedString、NSFileManager、NSNotification、NSProcessInfo等都廣泛地使用了聯合儲存。
參考連結:
相關文章
- iOS 屬性學習筆記iOS筆記
- Swift學習筆記第六篇(類,屬性,方法)Swift筆記
- PHP 手冊 (類與物件) 學習筆記二:屬性PHP物件筆記
- iOS學習筆記1(結合專案)---oc的@property屬性iOS筆記
- flutter 學習筆記【flutter 構造方法 TextField 屬性說明】Flutter筆記構造方法
- Vue學習筆記(六):監視屬性Vue筆記
- iOS學習筆記43 Swift(三)類iOS筆記Swift
- iOS筆記--UIButton常用屬性和監聽方法iOS筆記UI
- JavaScript中的物件學習筆記(屬性操作)JavaScript物件筆記
- HTML5 學習筆記 表單屬性HTML筆記
- Object C學習筆記10-靜態方法和靜態屬性Object筆記
- C#學習筆記-欄位、屬性、索引器C#筆記索引
- Runtime之分類新增屬性
- Java學習之類的屬性(轉)Java
- C#可擴充套件程式設計之MEF學習筆記(三):匯出類的方法和屬性C#套件程式設計筆記
- 《從零開始學Swift》學習筆記(Day 50)——擴充套件計算屬性、方法Swift筆記套件
- iOS Block學習筆記iOSBloC筆記
- iOS Runloop學習筆記iOSOOP筆記
- angular學習筆記(四)- input元素的ng-model屬性Angular筆記
- 《從零開始學Swift》學習筆記(Day 44)——重寫屬性Swift筆記
- 《從零開始學Swift》學習筆記(Day 32)——計算屬性Swift筆記
- 《從零開始學Swift》學習筆記(Day 33)——屬性觀察者Swift筆記
- Vue學習筆記(二)------axios學習Vue筆記iOS
- iOS 用runtime為分類新增成員變數或屬性iOS變數
- Vue學習筆記 —— axiosVue筆記iOS
- Axios用法–學習筆記iOS筆記
- iOS runtime學習筆記iOS筆記
- iOS指標學習筆記iOS指標筆記
- TS學習筆記(三):類筆記
- (JavaScript學習記錄):jQuery 屬性操作JavaScriptjQuery
- JavaScript學習筆記023-物件方法0包裝物件0靜態屬性JavaScript筆記物件
- GO 方法學習筆記Go筆記
- Go 方法 學習筆記Go筆記
- vue學習筆記(一)---- vue指令( v-bind 屬性繫結 )Vue筆記
- IOS學習筆記(頁面傳值:屬性傳值,協議代理傳值,閉包傳值)iOS筆記協議
- .net框架筆記——屬性框架筆記
- 統計學習方法筆記-感知機學習方法筆記
- iOS學習筆記02 UIScrollViewiOS筆記UIView