繼承自NSObject的不常用又很有用的函數(2)

來源:互聯網
上載者:User

函數調用

Objective-C是一門動態語言,一個函數是由一個selector(SEL),和一個implement(IML)組成的。Selector相當於門牌號,而Implement才是真正的住戶(函數實現)。

和現實生活一樣,門牌可以隨便發(@selector(XXX)),但是不一定都找得到住戶,如果找不到系統會給程式幾次機會來程式正常運行,實在沒出路了才會拋出異常。是objc_msgSend調用時,尋找SEL的IML的過程。咱們以這個流程為例看看其中涉及的很有用的函數。

 

 

圖:運行時尋找函數的流程

resolveInstanceMethod函數

原型:

+ (BOOL)resolveInstanceMethod:(SEL)name

這個函數在運行時(runtime),沒有找到SEL的IML時就會執行。

根據文檔,如果實現了添加函數代碼則返回YES,未實現返回NO。

實現的例子:

 dynamicMethodIMP(+ (aSEL ==], aSEL, (IMP) dynamicMethodIMP, 

根據Demo實驗,這個函數返回的BOOL值系統實現的objc_msgSend函數並沒有參考,無論返回什麼系統都會嘗試再次用SEL找IML,如果找到函數實現則執行函數。如果找不到繼續其他尋找流程。

forwardingTargetForSelector:

原型:

- ()forwardingTargetForSelector:(SEL)aSelector

流程到了這裡,。

返回參數是一個對象,如果這個對象的話,系統會將啟動並執行訊息轉寄給這個對象執行。否則,繼續尋找其他流程。

實現樣本:

+(- (- (*none =

當執行MyTestObject對象執行[myTestObject nonClassMethod]函數時,訊息會拋到NoneClass對象中執行。

 

methodSignatureForSelector:

原型:

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector

這個函數和後面的forwardInvocation:是最後一個尋找IML的機會。。

forwardInvocation:

原型:

- ()forwardInvocation:(NSInvocation *)anInvocation

真正執行從methodSignatureForSelector:返回的NSMethodSignature。在這個函數裡可以將NSInvocation多次轉寄到多個對象中,這也是這種方式靈活的地方。(forwardingTargetForSelector只能以Selector的形式轉向一個對象)

下面這個範例程式碼,詮釋了這種實現優勢:

 <Foundation/Foundation.h> *@property (retain) NSString **  - ( ((self == forKey: forKey:- (- (NSMethodSignature **sel = ([sel rangeOfString:].location ==          [NSMethodSignature signatureWithObjCTypes:         [NSMethodSignature signatureWithObjCTypes:- ()forwardInvocation:(NSInvocation *    NSString *key = ([key rangeOfString:].location ==         key = [[key substringWithRange:NSMakeRange(, [key length]-*        [invocation getArgument:&obj atIndex:        NSString *obj =&
doesNotRecognizeSelector:

原型:

- ()doesNotRecognizeSelector:(SEL)aSelector

作為找不到函數實現的最後一步,NSObject實現這個函數只有一個功能,就是拋出異常。

雖然理論上可以重載這個函數實現保證不拋出異常(不調用super實現),但是蘋果文檔著重提出“一定不能讓這個函數就這麼結束掉,必須拋出異常”。

使用情境

在一個函數找不到時,Objective-C提供了三種方式去補救:

1、調用resolveInstanceMethod給個機會讓添加這個實現這個函數

2、調用forwardingTargetForSelector讓去執行這個函數

3、調用methodSignatureForSelector(函數符號製造器)和forwardInvocation(函數執行器)靈活的將目標函數以其他形式執行。

如果都不中,調用doesNotRecognizeSelector拋出異常。

文章參考

https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/occ/clm/NSObject/

https://www.mikeash.com/pyblog/friday-qa-2009-03-27-objective-c-message-forwarding.html

http://blog.csdn.net/yiyaaixuexi/article/details/8970734

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.