Objective-C中的特定类类型参数

Dou*_*ugW 12 iphone class objective-c

我想接受一个Class对象作为我的一个类的构造函数的参数.它需要用它做很多自定义工作,我想从类的用户那里抽象出来.

例如,假设我的班级是经销商,我想用任何类型的车辆初始化它.

所以我有以下层次结构:

Dealership : NSObject

Vehicle : NSObject
Truck : Vehicle
Van : Vehicle
Car : Vehicle
Run Code Online (Sandbox Code Playgroud)

我想要做的是,在经销商内部,实现以下初始化程序:

- (id)initWithVehicle:(Class)aVehicle;
Run Code Online (Sandbox Code Playgroud)

除了不接受泛型类之外,我想将它限制为仅仅类型为"Vehicle"的类(其中包括我所有的继承类).我可以在初始化程序中测试此属性,但如果有一种方法可以在编译时强制执行此操作而不是等待运行时反馈,那将会很棒.

看来你可以引用Class来限制实现某个接口的类,所以我可以在那里做一些hackery.有没有办法引用特定类型的Class对象?

编辑 - 请注意,我编辑了示例类,因为原始示例有点误导.该示例仅用于演示目的,而不是我正在使用的实际类层次结构.

Cyp*_*ian 6

您可以确保使用协议检查:

- (id)initWithVehicle:(id<VehicleProtocol>)aVehicle;
...
}
Run Code Online (Sandbox Code Playgroud)

将对象声明为id会告诉编译器您不关心对象的类型,但您确实知道它符合指定的VehicleProtocol协议**.


Jon*_*pan 5

不是在编译时,但如果类无效,您可以释放self并返回nil:

- (id)initWithCar: (Class)carClass {
    self = [super init];

    if (self) {
        if (![carClass isSubclassOfClass:[Car class]]) {
            [self release];
            self = nil;
        } else {
            // Normal initialization here.
        }
    }

    return self;
}
Run Code Online (Sandbox Code Playgroud)

这是你最接近你想要的那种限制.

但是这种设计表明你需要重新思考你的类层次结构.Car你应该有一个Manufacturer类,而不是传递一个子类.像这样的东西:

@interface Manufacturer : NSObject
+ (id)manufacturerWithName: (NSString *)name;

- (NSArray *)allCars;
@property (readonly) Car *bestsellingCar;
// etc.
@end

#define kManufacturerVolvo [Manufacturer manufacturerWithName: @"Volvo"]
#define kManufacturerToyota [Manufacturer manufacturerWithName: @"Toyota"]
// etc.
Run Code Online (Sandbox Code Playgroud)

然后这个经销商的初始化程序:

- (id)initWithManufacturer: (Manufacturer *)aManufacturer;
Run Code Online (Sandbox Code Playgroud)