我有一些不同的viewControllers需要继承相同的属性,但是viewController的类型不同。例如,一个VC是常规UIViewController,而另一个是UISplitViewController。有没有办法让我有效地使用继承来确保它们都具有这些特定属性?或者我只是需要给每个人单独的声明?
答案 0 :(得分:3)
您可以使用UIViewController
上的类别来实现您想要的效果。您可以使用关联对象在类别中实现属性。
有关详细信息,请参阅Objective-C: Property / instance variable in category。
答案 1 :(得分:2)
您可以向UIViewController添加类别。由于UISplitViewController继承自UIViewController,因此它将具有该类别中定义的所有属性和方法。但是,类别有两个限制:
您无法添加支持实例变量。您可以创建属性,但它们不能有支持它们的实例变量。这意味着如果你覆盖了getter(和setter,如果是readwrite),那么它以某种方式读取(或写入)已经存在的属性,你就是好的。如果没有,您可以查看associated objects。
覆盖类别中的方法是禁忌。虽然没有什么能阻止你这样做,但如果另一个类别也覆盖了该方法,则会有未定义的行为。你只是不知道会执行哪种方法。如果你需要覆盖方法,子类化UIViewController会更好。但是,UISplitViewController将不知道这些属性,除非您将其子类化并添加相同的属性(在这种情况下,您将维护这些属性两次)。
答案 2 :(得分:1)
我不确定你到底需要什么。如果您不想(或不能)使用具有公共属性的公共超类,则可以始终编写协议。唯一不同的是,协议不会给你共同的实现,但强迫你写一个(所以你可以确定它在那里,如你所要求的)。
答案 3 :(得分:0)
为什么不使用共享基类设置继承并在init中设置这些共享属性?
//MyBaseVC.h
@interface MyBaseVC : UIViewController
@property (nonatomic, strong) NSString *myString;
@end
//VC1.h
@interface VC1 : MyBaseVC
@end
//VC2.h
@interface VC2 : MyBaseVC
@end
-----
//(MyBaseVC.m)
-(id) init {
self = [super init];
if(self){
self.myString = @"Hello world!";
}
return self;
}
// VC1.m
-(id) init {
self = [super init];
NSLog(@"%@", self.myString); // "Hello world!"
return self;
}
// VC2.m
-(id) init {
self = [super init];
NSLog(@"%@", self.myString); // "Hello world!"
return self;
}
此时,您可以直接引用子类对象上的属性:
NSLog(@"%@",myVc1.myString); //"Hello world!"
否则,当您以更通用的方式引用VC时,您总是可以引用它们的超类(MyBaseVC) - 例如,如果您需要将它们作为方法参数传递。
//-(void)doSomethingWithVC:(MyBaseVC *)vc;
[someObj doSomethingWithVc: vc1];