如何通过继承在自定义和Apple提供的类之间共享属性?

时间:2013-11-07 22:16:16

标签: ios objective-c inheritance uiviewcontroller

我有一些不同的viewControllers需要继承相同的属性,但是viewController的类型不同。例如,一个VC是常规UIViewController,而另一个是UISplitViewController。有没有办法让我有效地使用继承来确保它们都具有这些特定属性?或者我只是需要给每个人单独的声明?

4 个答案:

答案 0 :(得分:3)

您可以使用UIViewController上的类别来实现您想要的效果。您可以使用关联对象在类别中实现属性。

有关详细信息,请参阅Objective-C: Property / instance variable in category

答案 1 :(得分:2)

您可以向UIViewController添加类别。由于UISplitViewController继承自UIViewController,因此它将具有该类别中定义的所有属性和方法。但是,类别有两个限制:

  1. 您无法添加支持实例变量。您可以创建属性,但它们不能有支持它们的实例变量。这意味着如果你覆盖了getter(和setter,如果是readwrite),那么它以某种方式读取(或写入)已经存在的属性,你就是好的。如果没有,您可以查看associated objects

  2. 覆盖类别中的方法是禁忌。虽然没有什么能阻止你这样做,但如果另一个类别也覆盖了该方法,则会有未定义的行为。你只是不知道会执行哪种方法。如果你需要覆盖方法,子类化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];