2013-02-28 68 views
3

我知道使用類別覆蓋方法是一種令人沮喪的做法。儘管如此,我必須處理一些這樣做的代碼。當我運行下面的代碼時,我最初感到驚訝的是,在兩種情況下都調用了類別方法,但考慮鏈接器必須在鏈接時如何爲任何給定符號做出決定,這讓我感覺更好。在類別中重寫的方法是否總是優先於原始實現?

我的問題:假設除了我創建的其他類別不在其他類別中,我保證在我的類別中的實現始終是被調用的邏輯,只要它的標頭從某處導入?

someObject.h

#import <Foundation/Foundation.h> 

@interface SomeObject : NSObject 

- (void)doSomething; 

@end 

someObject.m

#import "SomeObject.h" 

@implementation SomeObject 

- (void)doSomething 
{ 
    NSLog(@"Original"); 
} 

@end 

someObject + Cat.h

#import <Foundation/Foundation.h> 

#import "SomeObject.h" 

@interface SomeObject (SomeObject) 

- (void)doSomething; 

@end 

someObject + Cat.m

#import "SomeObject+Cat.h" 

@implementation SomeObject (SomeObject) 

- (void)doSomething 
{ 
    NSLog(@"New!"); 
} 

@end 

someObjectUser.h

#import <Foundation/Foundation.h> 

@interface SomeObjectUser : NSObject 

- (void)useSomeObject; 

@end 

someObjectUser.m

#import "SomeObjectUser.h" 

#import "SomeObject.h" 

@implementation SomeObjectUser 

- (void)useSomeObject 
{ 
    [[SomeObject new] doSomething]; 
} 

@end 

Test.m

- (void)testExample 
{ 
    [[SomeObject new] doSomething]; 
    [[SomeObjectUser new] useSomeObject]; 
} 

結果

2013-02-28 11:32:37.417 CategoryExample[933:907] New! 
2013-02-28 11:32:37.419 CategoryExample[933:907] New! 
+0

@NikolaiRuhe我不同意,這些問題是根本不同的。 – 2013-02-28 16:58:42

+0

@MikeD問題有點不同,但答案對於這兩個問題都是有效的。 – Sulthan 2013-02-28 17:00:58

+0

我確實已經先讀過這個問題,現在可以看到那裏有答案,但是指南說未定義的行爲「不太可能是一個問題」,這讓我想知道這裏是否有更多的見解。 。 – 2013-02-28 17:28:50

回答

5

假定沒有其他類別是不是我創造的那些其他的戲, 我保證,在我的類實現將永遠是 因爲它是從 進口也就是說只要稱爲標頭中的邏輯某處?

無論您是否導入類別標題,我都懷疑這一點。頭文件是編譯器的信息;類在運行時添加到類中,並且在給定方法中使用哪個實現的選擇在運行時發生。更重要的是...

Objective-C Programming Guide

如果在一個類中聲明的方法的名稱是一樣的,在原來的類中的方法 ,或同一 另一個類別的方法類(甚至超類),的行爲是未定義的哪些 方法實現在運行時使用。如果您使用自己的類使用類別,但如果使用類別將方法添加到標準Cocoa或 Cocoa Touch類,可能會導致 問題,因此這不太可能是 問題。

(重點煤礦。)

考慮使用這個詞未定義的,我要說的是,這個問題的答案是沒有,也不能保證哪個執行,會使用時你重新實現一個類別中的現有方法。實際上,如果這個類是你自己的,那麼你的類的方法將很可能被選中,如果它在測試給定版本的編譯器和運行時工作,我相信它是可靠的。

+0

奇怪!除非我是瘋了,否則這是對舊行爲的一次突破性改變,即那些類別總是超過了非類別方法,但是沒有辦法使一個類別優先於另一個類別。接得好。 – Chuck 2013-02-28 19:52:13

+0

嘿,@Chuck。我不認爲有什麼變化 - 因爲類的方法必須在類創建後添加到類中,我完全期望類的實現總是被使用。但OP要求提供*保證*,顯然是一個很強的術語,並且文檔說* undefined *,所以... – Caleb 2013-02-28 20:06:39

+0

同樣來自文檔:「您試圖覆蓋的框架定義的方法本身可能已經在類別,所以哪些實現優先沒有被定義。「如果它沒有在每一種情況下都被定義出來,他們爲什麼不願意這樣說呢?我質疑此文檔... – 2013-02-28 20:06:53

0

UPDATE

在這樣,請回答下面鏈接,指向的Objective-C類文檔的鏈接已經死了。 Here is more up to date version。有一個關於避免名稱衝突的部分。


是,根據本SO answer,(我將發佈蘋果官方的鏈接,當我找到它)。

一些警告,原始方法將無法訪問,但您始終可以通過到super,不能保證在另一個類別(在同一類)聲明的方法將被覆蓋。

相關問題