UIViewController 的子类在调用 super 之前可以在 viewDidLoad 中进行一些初始化吗?

Posted

技术标签:

【中文标题】UIViewController 的子类在调用 super 之前可以在 viewDidLoad 中进行一些初始化吗?【英文标题】:Is it ok for subclass of a UIViewController to do some initialization in viewDidLoad before calling super? 【发布时间】:2013-07-24 20:10:50 【问题描述】:

所以,情况就是这样。我有一个基类 SSSAdEnabledTableViewController 和一个 XIB 文件,该文件在主视图内有一个 _contentView ,在该视图内有一个 _tableView 。基类用于呈现/隐藏广告。

然后我有许多从该基类继承的子类。除了那些需要非标准表格单元格(在本例中为 SSSDataEntryTableCell)的表格视图之外,大多数表格视图都可以正常工作。

如果我在调用 super 后尝试在我的子类的 viewDidLoad 中为该自定义表格单元格注册笔尖,它不起作用并且我的表格视图数据源和委托返回 nil 单元格。但是,如果我在调用 super 之前注册 NIB,它似乎工作得很好。

我的问题是,这是否是一种不好的做法,是否表明我做错了什么,进而导致需要这样做。

相关代码sn-ps如下:

基类 -- SSSAdEnabledTableViewController

@interface SSSAdEnabledEditTableViewController : UIViewController <ADBannerViewDelegate, UITableViewDataSource, UITableViewDelegate>

    // the data table
    UITableView *_tableView;

    // our inner view (to show/hide ads)
    UIView *_contentView;

    // our ad banner
    ADBannerView *_bannerView ;


@property (retain, nonatomic) IBOutlet UIView *contentView;
@property (retain, nonatomic) IBOutlet UITableView *tableView;
@property (nonatomic, retain) ADBannerView *bannerView ;

@end

它是 viewDidLoad 方法:

- (void)viewDidLoad

    [super viewDidLoad];

    //
    // set the appropriate background color
    //
    UIColor *clr = nil ;

    if ( [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad )
    
        clr = kSSSDefaultBackgroundColor ;
    
    else
    
        clr = [UIColor groupTableViewBackgroundColor] ;
    

    [[self view] setBackgroundColor:clr] ;

    [_tableView setAutoresizesSubviews:YES] ;    

这是子类的 viewDidLoad 方法之一:

- (void)viewDidLoad

    // Load the NIB file for our custom cell -- do this before [super viewDidLoad]!
    UINib *nib = [UINib nibWithNibName:kSSSDataEntryTableCell bundle:nil] ;

    // Register the NIB which contains the cell
    [_tableView registerNib:nib forCellReuseIdentifier:kSSSDataEntryTableCell] ;

    [super viewDidLoad];

    // ... does some other stuff not relevant to the question at hand ...

所以,如果我首先调用 [super viewDidLoad],代码似乎在 NIB 注册之前调用了 cellForRowAtIndexPath 的 UITableView 方法并且失败了。在通话之前使用它,它似乎工作得很好。

这是正确的做法还是我做错了?

谢谢!

【问题讨论】:

【参考方案1】:

您可以在执行自己的初始化代码后调用[super viewDidLoad]。如果你的超类希望你初始化一些它会使用的东西,那是完全合理的。

你可能不应该打电话给[_tableView setAutoresizesSubviews:YES]。表格视图有一个复杂的系统来布置它的子视图,你不知道它是否想要设置那个标志。

如果[self view] 实际上是表格视图,那么我相信对[[self view] setBackgroundColor:] 的调用是在调用tableView:cellForRowAtIndexPath:(间接)。您可以通过在tableView:cellForRowAtIndexPath: 中放置一个断点并在堆栈跟踪中查找setBackgroundColor:(和viewDidLoad)来检查这一点。

【讨论】:

谢谢!这就解释了为什么我看到对 tableView:cellForRowAtIndexPath 的调用。从来没有想过设置背景会导致这个问题。再次感谢。

以上是关于UIViewController 的子类在调用 super 之前可以在 viewDidLoad 中进行一些初始化吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 UIView 子类调用 UIViewController?

drawRect 在 UIView 子类上被调用,但不在 UIViewController 上

UIViewController 的子类在调用 super 之前可以在 viewDidLoad 中进行一些初始化吗?

动态子类化 UIViewController 的错误

从 UIViewController 方法更改 UIWindow 的呈现视图

从 UIViewController 调用自定义 UINavigationController 中的方法时目标错误