类组合如何在iOS中运行?

Jac*_*nkr 19 objective-c composition ios

比方说,我有属性AclassA和财产BclassB,我想classAB有两个属性AB.我仍然不明白如何使这一切都与作文有关.

我意识到这可以通过继承来完成,但我想学习如何使用组合来做到这一点.我看过一些例子,但我仍然不知道它是如何运作的.

ben*_*ado 21

您创建了一个新类,它具有classA和classB的实例作为成员变量.然后通过传递get/set方法来实现属性.

@interface ClassAB
{
    ClassA *objectA;
    ClassB *objectB;
}
@property (nonatomic,strong) id propertyA;
@property (nonatomic,strong) id propertyB;
@end

@implementation ClassAB
- (id)propertyA { return objectA.propertyA; }
- (void)setPropertyA:(id)value { objectA.propertyA = value; }
- (id)propertyB { return objectB.propertyB; }
- (void)setPropertyB:(id)value { objectB.propertyB = value; }
@end
Run Code Online (Sandbox Code Playgroud)

这就是组成.有些语言有特殊的语法来执行此操作(例如,在Ruby中,您可以在一个类/模块中包含一组方法),但Objective-C不允许这样做.

可以在Objective-C中执行的一件事是捕获发送到您的对象的消息,这些消息没有关联的方法,并将它们转发给另一个对象.如果您正在编写一个将作为另一个类构成的类,或者如果要转发许多不同的消息并且您不想手动将它们全部写出,则此技巧非常有用.

使用消息转发的缺点是您放弃了某些控制,并且在您的类或转发类处理消息时可能更难预测.例如,如果超类实现了一个方法,那么将执行该方法并且不会调用转发代码.

  • 我相信这是更好的可读性解决方案.理查兹解决方案是一个巧妙的技巧,但我总是把实用主义和可读性放在棘手的代码上.我觉得风格很重要 (2认同)

Ric*_*III 8

假设ClassAClassB按照您的说法实现,这非常有效,并且可以轻松扩展.

@interface ClassAB : NSObject

@property int a;
@property int b;

@property ClassA *aObject;
@property ClassB *bObject;

@end

@implementation ClassAB

@dynamic a, b;
@synthesize aObject, bObject;

-(id) forwardingTargetForSelector:(SEL)aSelector
{
    if ([aObject respondsToSelector:aSelector])
        return aObject;
    else if ([bObject respondsToSelector:aSelector])
        return bObject;

    return nil;    
}

@end

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        ClassA *a = [ClassA new];
        ClassB *b = [ClassB new];

        ClassAB *ab = [ClassAB new];
        ab.aObject = a;
        ab.bObject = b;

        ab.a = 10;
        ab.b = 20;

        NSLog(@"%i, %i", a.a, b.b); // outputs 10, 20
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)