2012-11-18 57 views
2

我正在Objective-C中進行一些動態編程工作,並且已經通過Objective-C Runtime編程指南正面讀取並能夠完成大部分我需要的工作,但是我沒有做的一件事想通了,是如何動態調用一個方法,我有它的字符串表示。如何使用NSString或const char *名稱動態調用Objective-C中的方法?

本質上,我動態地做了一個屬性查找,看看我的對象是否有一個屬性與使用class_copyPropertyList的列表匹配,然後循環並通過從plist文件填充的NSMutableDictionary進行匹配。當找到匹配項時,我想執行該屬性。我無法預先知道可能存在哪些匹配,因爲這是一個將被打包到許多不同應用程序中的庫。

回答

7

使用NSSelectorFromString從一個NSString創建SEL。然後您可以使用performSelector方法之一執行它。

設置屬性動態:

SEL setter = NSSelectorFromString(@"setProperty:"); 
[myObject performSelector:setter withObject:newValue]; 

獲取屬性動態:

SEL getter = NSSelectorFromString(@"property"); 
id myProperty = [myObject performSelector:getter]; 

對於更復雜的方法可以使用NSInvocationNSMethodSignature

SEL action = NSSelectorFromString(@"someMethod:withArguments:"); 
NSMethodSignature *signature = [myObject methodSignatureForSelector:action]; 
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; 
[invocation setArgument:arg1 atIndex:2]; // indices 0 and 1 are reserved. 
[invocation setArgument:arg2 atIndex:3]; 
[invocation invokeWithTarget:myObject]; 
id returnedObject; 
[invocation1 getReturnValue:&returnedObject]; 
+2

「如果你也對返回值感興趣」 - 你可以用'performSelector:'來做到這一點。 – 2012-11-18 15:37:50

+1

您應該首先檢查屬性是否具有自定義getter或setter,而不是假定它們遵循名稱/ setName模式。你可以通過挖掘property_getAttributes()的結果來確定這些定製訪問器是否以及是什麼。請參閱[Objective-C運行時編程指南]中的相關章節(http://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html#//apple_ref/doc/uid/TP40008048-CH101-SW6) –

+0

我試過了,它的工作原理與我所希望的一樣,但是當屬性類型是簡單數據類型(如int)而不是實際類類型時失敗。有沒有辦法處理這個問題,除了必須轉換所有基本數據類型? – bigtunacan