2014-04-12 20 views
1

假設我有一個對象,MyClass的一個實例。在Objective-C中,可以通過發送消息或使用NSObject的「執行」來要求Object「執行」選擇器。Objective-C - 有沒有一種方法讓對象直接執行方法IMP,就好像它自己一樣?

這個選擇器必須在編譯時定義爲類定義的一部分,更確切地說就是該類的實例方法,或者在Obj-C運行時的幫助下,將方法添加到(整個)MyClass在運行時用class_addMethod。

我的問題如下:

是否可以發送對象的IMP,並要求它來執行它本身?基本上我需要Objects,MyClass的不同實例在沒有整個MyClass知道它的情況下自行執行。基本上我會調用這些「每個對象方法」,一個Object1獲取這個IMP自己執行,然後另一個Object2獲得一個不同的IMP,等等。這些IMP被存儲在其他地方,並且它知道並決定將事物發送到哪裏的Object。

+1

你究竟想在這裏完成什麼?這聽起來像是一個非常大的黑客,當實際解決方案更簡單時,這可能最終成爲一種創可貼。 –

+0

爲了更加精確,在運行時我有一個ContextClass的實例,並且在其中一個方法中我使用了幾個塊內部的變量。我想發送這些塊(它們自動從當前範圍獲取變量引用)從它們生成IMP,然後將這些IMP從上下文實例發送到其他對象以自行執行,實質上使得對象知道其中的其他對象通過這些塊的上下文。對象應該對自身執行這個IMP,就好像我對它調用了[self anonymousMethod]一樣。讓我知道如果你有它! – unmircea

回答

0

是,工程

#import <Foundation/Foundation.h> 
#import <objc/runtime.h> 

@interface DonorTemplateClass : NSObject 
- (void)testMethod:(NSString*)aStringAsParameter; 
@end 
@implementation DonorTemplateClass 
- (void) testMethod:(NSString*)aStringAsParameter { 
    NSLog(@"%@ :: %@", self.class, aStringAsParameter); 
} 
@end 

@interface AClass : NSObject 
@end 
@implementation AClass 
@end 

@interface AnotherClass : NSObject 
@end 
@implementation AnotherClass 
@end 

int main(int argc, char *argv[]) { 
    @autoreleasepool { 
     SEL justTheMethodSelector = @selector(testMethod:); 
     IMP justTheMethodImplementation = class_getMethodImplementation([DonorTemplateClass class], justTheMethodSelector); 

     AClass *anAClassInstance = [[AClass alloc] init]; 
     AnotherClass *anotherClassInstance = [[AnotherClass alloc] init]; 

     NSString *aString = @"Test1"; 

     typedef void (*MyTypeName)(id,SEL, NSString*); // more info about the block syntax on http://goshdarnblocksyntax.com scroll down to "typedef" 
     MyTypeName blockName = (MyTypeName)justTheMethodImplementation; 

     blockName(anAClassInstance, justTheMethodSelector, aString); 
     blockName(anotherClassInstance, justTheMethodSelector, aString); 
    } 
} 

請注意,我投我的IMP到typedef定義指針類型。它編譯罰款時,我只是打電話給我,但objc_retain崩潰,然後對我來說......所以我會說你需要在使用它們之前鍵入你的IMP,但然後你可以在任何合適的類別的背景下執行它們

+0

也要注意,雖然你可以將ANY類實現到你的實現中,但如果實現訪問類本身的特定成員變量,它可以打破 –

+0

喜歡你的例子,但它非常簡潔。你能/我編輯它使其更加冗長?如果有幫助,如果因爲語法對這些東西來說很奇怪。 – unmircea

+0

爲了更加精確,在運行時我有一個ContextClass的實例,並且在其中一個方法中我使用了幾個塊內部的變量。我想發送這些塊(它們自動從當前範圍獲取變量引用)從它們生成IMP,然後將這些IMP從上下文實例發送到其他對象以自行執行,實質上使得對象知道其中的其他對象通過這些塊的上下文。對象應該對自身執行這個IMP,就好像我對它調用了[self anonymousMethod]一樣。讓我知道如果你有它!從它 – unmircea

0

IMP只是一個常規C函數指針的typedef。它的意思是指向方法實現,它是C函數,第一個參數是對象,第二個參數是選擇器。 「一個執行IMP的對象」僅僅意味着調用C函數,將對象作爲第一個參數傳遞,並將選擇器作爲第二個參數傳遞。

你說你希望能夠「發送一個對象的IMP並要求它自己執行它」(即調用通過對象和選擇器的IMP),但你不希望「整個MyClass知道關於它「(我認爲你不希望它是一種方法)。

所以基本上,這聽起來像你只是想要一堆獨立的C函數,而不是方法,你可以調用,根據需要傳遞各種對象。你可以隨意存儲這些C函數指針。是對的嗎?

+0

是的。你的照片是正確的。更確切地說,在運行時我有一個ContextClass的實例,並且在其中的一個方法中我有幾個塊內部使用的變量。我想發送這些塊(它們自動從當前上下文中獲取變量引用)從它們生成一個IMP,然後將這些IMP從上下文實例發送到其他對象以自己執行,實質上使對象知道其中的其他對象通過這些塊的上下文。讓我知道如果你有它! – unmircea

相關問題