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等都廣泛地使用了聯合儲存。
參考連結:
相關文章
- Python 動態新增例項屬性,例項方法,類屬性,類方法Python
- PHP 手冊 (類與物件) 學習筆記二:屬性PHP物件筆記
- flutter 學習筆記【flutter 構造方法 TextField 屬性說明】Flutter筆記構造方法
- iOS學習筆記43 Swift(三)類iOS筆記Swift
- Vue學習筆記(六):監視屬性Vue筆記
- JavaScript中的物件學習筆記(屬性操作)JavaScript物件筆記
- C#學習筆記-欄位、屬性、索引器C#筆記索引
- iOS Block學習筆記iOSBloC筆記
- JavaScript學習筆記023-物件方法0包裝物件0靜態屬性JavaScript筆記物件
- iOS學習筆記02 UIScrollViewiOS筆記UIView
- (JavaScript學習記錄):jQuery 屬性操作JavaScriptjQuery
- vue學習筆記(一)---- vue指令( v-bind 屬性繫結 )Vue筆記
- Matlab_GUI學習筆記(三)——常用物件的屬性之FigureMatlabGUI筆記物件
- TS學習筆記(三):類筆記
- 線性基學習筆記筆記
- GO 方法學習筆記Go筆記
- 小碼哥iOS學習筆記第六天: initialize方法iOS筆記
- iOS 開發:『Runtime』詳解(四)獲取類詳細屬性、方法iOS
- React學習手記2-屬性校驗和預設屬性React
- 統計學習方法筆記-感知機學習方法筆記
- iOS學習筆記05 觸控事件iOS筆記事件
- iOS學習筆記39 ReactiveCocoa入門iOS筆記React
- 抽象類特點 學習筆記抽象筆記
- java學習筆記(包裝類)Java筆記
- 學習筆記——物件方法整理筆記物件
- 統計學習方法筆記筆記
- 類的靜態屬性和方法
- 線性代數學習筆記(二)+貪心學習筆記(一)(2024.10.5)筆記
- Android學習筆記之檔案分類和線性佈局Android筆記
- WPF依賴屬性的正確學習方法
- 如何實現分類中新增弱引用屬性
- Java Math類方法學習記錄Java
- Xamarin 學習筆記 - 配置環境(Windows & iOS)筆記WindowsiOS
- iOS學習筆記04 檢視切換iOS筆記
- iOS學習筆記14 網路(三)WebViewiOS筆記WebView
- iOS學習筆記06 手勢識別iOS筆記
- iOS學習筆記47 Swift(七)泛型iOS筆記Swift泛型
- iOS學習筆記18 CoreData你懂的iOS筆記
- iOS學習筆記--PresentedVC自定義彈窗iOS筆記