2010-10-14 48 views
3

是否可以訪問對象超類(或祖父)的超類方法?可可祖父

例如:

GrandFatherObject : NSObject 
SuperObject : GrandFatherObject 
SelfObject : SuperObject 

從自體客體:

- (void)overriddenMethod 
{ 
    // For Self 
    someCode(); 

    // For Parent 
    [super overriddenMethod]; 

    // For GrandParent 
    ??? 
} 

爲什麼要做到這一點我只能訪問自身客體(不能修改超對象或GrandFatherObject)

+0

另請參閱http://stackoverflow.com/questions/3701594/how-to-call-a-grandparent-method – 2010-10-15 00:32:08

回答

10

是的,你可以做到這一點,但它需要多一點的代碼,而不僅僅是調用super

更多或更少,這將會是這樣的:

#import <objc/runtime.h> 

struct objc_super grandsuper; 
grandsuper.receiver = self; 
grandsuper.class = class_getSuperclass(class_getSuperclass([self class])); 

//if _cmd has a non-struct return value: 
id grandsuperReturnValue = objc_msgSendSuper(&grandsuper, _cmd, arg1, arg2, ...); 
+1

此外,由於所有通過objc_msgSendSuper發送的參數都使用var_arg列表,所以您的所有方法參數都必須是可變參數列表兼容的。例如float和short將不起作用(在var_arg列表中,它們分別被提升爲double和int,並且不會被您的方法正確解析)。 – 2010-10-18 05:54:47

5

?如果您認爲這是必要的,您應該重新考慮您的班級設計。當然,您始終可以在overriddenMethod的父級實施中致電super

爲了正確的封裝,子類不需要知道其他父類以外的任何東西。否則,你會在繼承層次結構中產生緊密的雙向耦合。惡夢。

+5

我同意這不太可能是必要的,但不難想象什麼時候你可能想要去做吧。例如,如果您正在編寫類集羣,並且父集羣類將'-init'重寫爲'[self release]'並返回一個新的適當子類型的已分配對象,那麼子類將不會*調用' [super init]'但可能想要調用'[grandsuper init]'而不是 – 2010-10-14 19:49:05

+0

我最終確定了一種不使用「grandsuper」的方法,但它仍然很複雜。我的特殊場景是:我將一個NSView放入一個WebHTMLView中(我正在努力將可可視圖放入WebView對象的內部),雖然它們運行良好並且看起來很棒,但我無法點擊它們。這是因爲WebHTMLView(一個私有類)重新定義了hitTest:所以我分類了WebView(我的自我),並且重寫了WebView的hitTest,檢查它是否是我想要的命中(如果是),我會調用grandparent(NSView)hitTest ,否則父(WebHTMLView)hitTest。儘管 – BadPirate 2010-10-15 17:18:27

3

雖然與objc_msgSendSuper打()肯定是好玩的,你爲什麼不採取簡單的方法,並創建自目標實施分類,像

@interface SuperObject (ForSelfObject) 
    - (id)grandFatherOverridenMethod; 
@end 

@implementation SuperObject (ForSelfObject) 
    - (id)grandFatherOverridenMethod { 
    return [super overridenMethod]; 
    } 
@end 

你說你不能修改超對象,這並不意味着你不能擴展它。我在這裏錯過了任何主要的缺點嗎?

+0

+1巧妙的解決方案! :) – 2010-10-15 03:47:48

+0

虛擬-1(實際下調投票將是苛刻的國際海事組織)這將是一場災難,因爲你沒有延伸超級對象,你正在改變其行爲的一部分。它可能是在繞過的方法中做的事情,這對於正確操作是必不可少的。 – JeremyP 2010-10-15 09:16:28