2013-02-25 41 views
8

是否可以在運行時更改對象的超類?如果是這樣,怎麼樣?動態更改對象的超類

+0

查看http://stackoverflow.com/questions/11221110/my-isa-swizzling-breaks-kvo查看isa swizzle的示例。 – mttrb 2013-02-25 05:29:19

+1

另外,「對象的超類」是什麼意思?一個*對象*沒有超類。一個對象有一個類,它的類有一個超類。但是,如果您改變對象類的超類,那麼該類的所有成員都將受到影響,而不僅僅是該單個對象。 – 2013-02-25 05:31:00

+2

爲什麼超類不是現在的類?當前課程發生了什麼?你必須先仔細思考 – 2013-02-25 05:33:44

回答

11

一個簡短的問題,一個簡短的回答:是的,ISA混寫

What Makes Objective C Dynamic?, page 66


一個例子:

我有一個處理一個REST的API連接的類,它是稱爲APIClient。在測試中,我想連接到不同的服務器。

在測試目標I子類APIClient

#import "ApiClient.h" 

@interface TestApiClient : ApiClient 
//… 
@end 


@interface TestApiClient() 
@property (nonatomic, strong, readwrite) NSURL *baseURL; 

@end 


@implementation TestApiClient 

- (NSMutableURLRequest *)requestWithMethod:(NSString *)method 
             path:(NSString *)path 
           parameters:(NSDictionary *)parameters 
{ 
    self.baseURL = [NSURL URLWithString:@"http://localhost:8000/"]; 
    return [super requestWithMethod:method path:path parameters:parameters]; 
} 

@end 

在單元測試I類做混寫 #進口

@implementation APIUnitTests 


+(void)load 
{ 
    client = [[ApiClient alloc ] init]; 
    object_setClass(client, [TestApiClient class]); 
} 

//… 
@end 

這CAS是保存,因爲我首先創建的一個子類基類,然後用子類替換後者。由於子類也是一個基類,這是有效的繼承。

+1

這聽起來非常危險。你爲什麼想要? – 2013-02-25 05:35:27

+1

如果做得對,它是非常強大的,蘋果使用它的KVO:http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/KeyValueObserving/Articles/KVOImplementation.html – vikingosegundo 2013-02-25 05:36:39

+0

我親自使用它來檢查代碼:我創建子類並覆蓋我感興趣的方法來記錄一些信息並在超級方法上調用原始方法。 – vikingosegundo 2013-02-25 05:40:12