gpt4 book ai didi

objective-c - Objective-C 支持 traits/mixins 吗?

转载 作者:太空狗 更新时间:2023-10-30 03:21:58 24 4
gpt4 key购买 nike

是否有任何技术可以在 Objective-C 中模拟 traits 或 mixins?

例如,在 Scala 中,我可以这样做:

trait ControllerWithData {
def loadData = ...
def reloadData = ...
def elementAtIndex = ...
}

trait ControllerWithStandardToolbar {
def buildToolbar = ...
def showToolbar = ...
def hideToolbar = ...
}

class MyTableController extends ControllerWithData
with ControllerWithStandardToolbar {
def loadView = {
super.loadView

loadData
buildBar
}
}

它基本上是一种将多个功能组合(或混合)到一个类中的方法。所以现在我有一个通用的 UIViewController,我的所有 Controller 都从它继承子类,但如果我能分解它并让特定的 Controller 继承特定的行为,它会更整洁。

最佳答案

没有直接的语言支持,但您可以通过消息转发完成类似的事情。假设您有特征类“Foo”和“Bar”,它们分别定义了方法“-doFoo”和“-doBar”。您可以定义您的类(class)以具有特征,如下所示:

@interface MyClassWithTraits : NSObject {
NSMutableArray *traits;
}
@property (retain) NSMutableArray* traits;

-(void) addTrait:(NSObject*)traitObject;
@end

@implementation MyClassWithTraits
@synthesize traits;

-(id)init {
if (self = [super init]) {
self.traits = [NSMutableArray array];
}
return self;
}

-(void) addTrait:(NSObject*)traitObject {
[self.traits addObject:traitObject];
}

/* Here's the meat - we can use message forwarding to re-send any messages
that are unknown to MyClassWithTraits, if one of its trait objects does
respond to it.
*/
-(NSMethodSignature*)methodSignatureForSelector:(SEL)aSelector {
// If this is a selector we handle ourself, let super handle this
if ([self respondsToSelector:aSelector])
return [super methodSignatureForSelector:aSelector];

// Look for a trait that handles it
else
for (NSObject *trait in self.traits)
if ([trait respondsToSelector:aSelector])
return [trait methodSignatureForSelector:aSelector];

// Nothing was found
return nil;
}

-(void) forwardInvocation:(NSInvocation*)anInvocation {
for (NSObject *trait in self.traits) {
if ([trait respondsToSelector:[anInvocation selector]]) {
[anInvocation invokeWithTarget:trait];
return;
}
}

// Nothing was found, so throw an exception
[self doesNotRecognizeSelector:[anInvocation selector]];
}
@end

现在,您可以创建 MyClassWithTraits 的实例,并添加您想要的任何“特征”对象:

MyClassWithTraits *widget = [[MyClassWithTraits alloc] init];
[widget addTrait:[[[Foo alloc] init] autorelease]];
[widget addTrait:[[[Bar alloc] init] autorelease]];

您可以在 MyClassWithTraits 的 -init 方法中对 -addTrait: 进行这些调用,如果您希望该类的每个实例都具有相同类型的特征。或者,您可以像我在这里所做的那样进行操作,这样您就可以为每个实例分配一组不同的特征。

然后您可以调用 -doFoo-doBar 就好像它们是由小部件实现的一样,即使消息被转发到它的特征对象之一:

[widget doFoo];
[widget doBar];

(编辑:添加了错误处理。)

关于objective-c - Objective-C 支持 traits/mixins 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5601126/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com