来自超类的重写属性

时间:2012-03-05 20:06:03

标签: iphone objective-c ios inheritance properties

我有一个UIViewController的超类 - MasterViewController,它声明了一个名为itemsViewController的属性。这声明了一个从MasterViewController调用的方法,并通过IB中的故事板连接起来。

我有一个MasterViewController的子类,它将此属性重新声明为特定的iPad版本,但我无法从父类访问重新声明的属性。

MasterViewController

@interface MasterViewController : UIViewController {
}

@property (nonatomic, strong) IBOutlet ItemsViewController *itemsViewController;
@end

@implementation MasterViewController
@synthesize itemsViewController;

-(void)viewDidLoad {
// I can access itemsViewController in viewDidLoad.

}
@end 

MasterViewController_iPad

@interface MasterViewController_iPad : MasterViewController {
    IBOutlet ItemsViewController_iPad *_itemsViewController;
}

@property (nonatomic, strong) IBOutlet ItemsViewController_iPad *itemsViewController;
@end

@implementation MasterViewController_iPad
@synthesize itemsViewController = _itemsViewController;

-(void)viewDidLoad {
    [super viewDidLoad];
// when I call super viewDidLoad,  itemsViewController is nil, as though the property hasn't been overriden
// _itemsViewController is not nil in viewDidLoad.
}
@end 

我是否误解了Objective-C中属性继承的工作方式?

2 个答案:

答案 0 :(得分:1)

覆盖超类方法时,无法更改方法的类型签名。

MasterViewController有以下方法:

(void)setItemsViewController:(ItemsViewController *)foo
(ItemsViewController *)itemsViewController

但是你试图给MasterViewController_iPad这些方法:

(void)setItemsViewController:(ItemsViewController_iPad *)foo
(ItemsViewController_iPad *)itemsViewController

您不能这样做:您不能重载相同的方法名称,但参数的类型不同。

如果ItemsViewController_iPadItemsViewController的子类,则快速解决方案是保留与MasterViewController中相同的签名,但只需在设置属性时使用ItemsViewController_iPad

答案 1 :(得分:0)

如果您想覆盖属性,可以使用类别。这是一个例子:

PDFFileChooserViewController PDFFileModelPDFFilesDataSource以及与此属性相关的逻辑。

@class PDFFileModel, PDFFilesDataSource;
@interface PDFFileChooserViewController : UIViewController

@property (nonatomic, strong) PDFFileModel* selectedModel;
@property (nonatomic, strong) PDFFilesDataSource*dataSource;

@end

然后,我想添加特定的ViewController,用于从Dropbox中选择文件,但我的模型还有一些其他字段,例如dropboxPath,而我的DropboxDataSource使用其他方式获取文件。所以我决定创建类别并覆盖这些属性:

#import "PDFFileChooserViewController.h"


@class DropboxFileModel,DropboxDataSource;

@interface DropboxViewController : PDFFileChooserViewController
@end

@interface DropboxViewController (ModelCategory)
@property(nonatomic, strong) DropboxFileModel* selectedModel;
@property(nonatomic, strong) DropboxDataSource* dataSource;
@end

请注意,此类别将在DropboxViewController中可见,只有我可以使用该属性进行操作,但另一个类只能看到超类接口