1

我正在爲Spotlight寫一個SIMBL插件,並且我正在嘗試創建一個內部Spotlight類型的子類。儘管我可以使用class-dump直接從可執行文件獲取頭文件,但我沒有要鏈接的靜態庫,因此編譯這些內部類之一的子類失敗(即使這些類在運行時可用)。我一直在關注Mike Ash的subclassing classes at runtime的指示,但這很不方便。有什麼方法可以在鏈接時沒有超類的情況下創建Objective-C類的子類?子類沒有與超類鏈接的Objective-C類?

+2

'NSClassFromString()'和'objc_allocateClassPair()'是你的朋友。不,它不會像編譯時那樣方便。 – 2014-11-02 20:44:21

+0

啊,唉。我希望有一個更簡單的方法... – nate777 2014-11-03 01:44:53

回答

0

這是完全可能的,而且實際上並不是非常困難。下面是與NSValue一個簡單的例子:

@interface MySubclass : NSObject 

-(void) someMethod; 

@end 

@implementation MySubclass 

+(void) load { 
#pragma clang diagnostic push 
#pragma clang diagnostic ignored "-Wdeprecated" 

    class_setSuperclass(self, NSClassFromString(@"NSValue")); 

#pragma clang diagnostic pop 
} 

-(void) someMethod { 
    NSLog(@"%@", [self superclass]); 
} 

-(const char *) objCType { 
    return @encode(int); 
} 

-(void) getValue:(void *)value { 
    if (value) { 
     *((int *) value) = 10; 
    } 
} 

@end 

int main() { 
    MySubclass *theSubclass = [MySubclass new]; 
    [theSubclass someMethod]; 

    NSLog(@"%i", [theSubclass isKindOfClass:[NSValue class]]); 
} 

class_setSuperclass,而過時,仍然有一個實現爲OS X 10.10,類被註冊後可以來完成。但是,我還沒有完全探究在創建該類的實例後更改類的超類的效果,因此請注意,如果要在+load+initialize之後的任何點執行此操作。

這可能會導致難以調用super上的方法,但可以通過簡單地聲明NSObject(或您選擇在您的實現中繼承的任何超類)上的類別來獲得此信息。