2012-05-04 32 views
1

如何用某種協議的通用實現來裝飾類?如何實現協議一般與類別?

對不起,這可能是一個明顯的問題。我是新來的客觀的C,所以我仍然只是一點點踩水。

我已經得到了我想要一個通用的實施方案:

@protocol SelectableElement <NSObject> 
@property BOOL selected; 
@end 

我有一對夫婦的對象,我想可選:

@interface Widget : NSObject <SelectableElement> 
@end 

@interface Duhicky : NSObject <SelectableElement> 
@end 

我」 d喜歡做的是一次編寫協議的實現,並確保兩個對象都以這種方式實現。

我不認爲我可以寫一個通用類,並將其綁定到兩個,所以我想這樣做是爲了增加實現對通用類NSObject的範疇的一種方式:

@implementation NSObject (Selectable) 
- (BOOL)selectable 
{ 
    if (![self conformsToProtocol:@protocol(SelectableElement)]) return; 

    return YES; // Use associative storage for this? 
} 

- (void)setSelectable:(BOOL)selectable 
{ 
    if (![self conformsToProtocol:@protocol(SelectableElement)]) return; 

    // set this associatively? 
} 
@end 

中當然,我不能定義一個屬性變量來做到這一點,我需要使用關聯對象存儲......我沒有在這裏演示過。

這是將可選行爲一般添加到實現可選元素協議的任何事情的唯一方法嗎?還是有更明顯的方式,我失蹤了?

我當然可以使用繼承來實現這個簡單的例子,但這隻適用於以這種方式實現單個協議。這種方法我認爲是天作之合,還是黑客?

Joe

回答

1

創建一個類來實現協議即。 SelectableObject然後使WidgetDuhicky類繼承SelectableObject。

+0

+1:或換句話說,Widget和Duhicky類應該是SelectableObject的子類。 – lnafziger

0

這聽起來像你想在Ruby中像Mixin一樣。不幸的是,在Objective-C的語言層面上這是不可能的。分享行爲的唯一途徑是通過繼承。

也就是說,你可以用Objective-C運行時做一些技巧來實現你想要的。這可能不是一個好主意,針對你正在使用的語言,但如果你想探索這個選項看看這裏:http://cocoadev.com/wiki/MethodSwizzling

0

不幸的是,這是繼承是一個特別不適合的情況之一問題。

但是,您可以在Cocoa框架中看到(ab)繼承的使用(NSResponderUIResponder)。如果您不控制繼承結構(某個外部框架中的某個對象),則需要使對象可選,否則會遇到問題。

您在NSObject上的類別將起作用,在這種情況下,我認爲它更可取。乍看之下,對於每一個物體來說,這些方法似乎都很重視,但由於caching in the method lookup mechanism,性能損失很小。