[swift-users] Swift alternative for heterogeneous collection of objects with "generic" contents.

Mikhail Seriukov zloisop at gmail.com
Fri Jun 30 00:59:12 CDT 2017


Hello everyone,
In objc there is quite common pattern when we use a base class with a type
property and concrete subclasses where type is uniquely identifying the
subclass.
We can then safely put subclasses objects into an array and then safely
downcast them when needed.
This kind of behaviour is commonly used in data sources implementations.

Like this:

typedef NS_ENUM(NSUInteger, CellDecriptorType) {
    CellDecriptorTypeUnknown,
    CellDecriptorType1,
    CellDecriptorType2
};

@interface BaseCellDescriptor : NSObject

@property (nonatomic, readonly) CellDecriptorType type;
@property (nonatomic, strong) id value;

@end


@interface CellDescriptor1 : BaseCellDescriptor
@end

@implementation CellDescriptor1

- (CellDecriptorType)type {
    return CellDecriptorType1;
}

- (NSString *)value {
return @"string value";
}

@end


@interface CellDescriptor2 : BaseCellDescriptor
@end

@implementation CellDescriptor2

- (CellDecriptorType)type {
    return CellDecriptorType2;
}

- (NSNumber *)value {
return @42;
}

@end

And somewhere later we do:

- (void)doWorkWithCellDescriptors:(NSArray<BaseCellDescriptor *>
*)descriptors {
    for (BaseCellDescriptor *descriptor in descriptors) {
        CellDecriptorType type = descriptor.type;
        switch(type) {
            case CellDecriptorType1: {
                CellDescriptor1 *aDescriptor = (CellDescriptor1
*)descriptor;
                NSString *value = aDescriptor.value;
                // Do something with value
                break;
            }
            case CellDecriptorType2: {
                CellDescriptor2 *aDescriptor = (CellDescriptor2
*)descriptor;
                NSNumber *value = aDescriptor.value;
                // Do something with value
                break;
            }
            case CellDecriptorTypeUnknown:
            default: {
                // Handle error
                break;
            }
        }
    }
}


I want to implement it swifty way. So the questions are:
0. Is it a bad practice to use this pattern and how we can avoid it?
1. Is it possible to avoid inheritance here and only use generic protocols
and how?
2. Is it possible to avoid downcasting if using this pattern in swift?


I've found the solution that seems to be a good example in this project
https://github.com/xmartlabs/Eureka.
They maintain both inheritance hierarchy and protocol hierarchy.

3. Is it a good practice to implement such tasks like in Eureka project,
what are the pros and cons of it?

Thanks for your time!
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20170630/884fa98a/attachment.html>


More information about the swift-users mailing list