【问题标题】:Overridden properties from superclass超类的重写属性
【发布时间】:2012-03-23 07:28:33
【问题描述】:

我有一个 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 中属性继承的工作方式?

【问题讨论】:

    标签: iphone objective-c ios inheritance properties


    【解决方案1】:

    重写超类方法时,不能更改方法的类型签名。

    MasterViewController 有这些方法:

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

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

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

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

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

    【讨论】:

      【解决方案2】:

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

      我有PDFFileChooserViewControllerPDFFileModelPDFFilesDataSource 以及与此属性相关的一些逻辑。

      @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 中可见,我可以使用该属性进行操作,但其他类只能看到超类接口

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-03-13
        • 1970-01-01
        • 2016-10-18
        • 1970-01-01
        • 1970-01-01
        • 2017-04-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多