我希望我的项目有一个BaseViewController
类(继承自UIViewController
),它可以作为我项目中其他视图控制器的基类。这是为了添加一些东西,比如一个普通的进度HUD,一个刷新按钮&网络更新机制,也许是一个错误对话框,可以通过每个子类自定义文本,等等
至关重要的是,我希望能够将此功能添加到UIViewController
子类和UITableViewController
子类中,但我无法将自己插入到UITableViewController
类层次结构中,因此实际上我需要BaseUIViewController
和BaseUITableViewController
,但如果我这样做,我必须实现两次更改并保持它们同步。
为BaseViewController
子类和BaseTableViewController
子类都可以访问的公共代码提供一个单独的位置的最佳方法是什么?我只想在我的代码中有一个地方,在那里我必须处理常见的任务。
1) 我曾考虑过使用具有关联引用的类别,但这里的问题是,我需要自定义ViewController生命周期类的实现,如viewDidLoad:,这不是一个好主意。
2) 我可以完全跳过UITableViewController
,从BaseViewController构建自己的BaseTableViewController
,实现tableView
delegate
&datasource
是我自己的方法,但我不太想在这里跳过苹果的控制器实现。
3) 我可以让BaseViewController
从UIViewController
继承,BaseTableViewController
从UITableViewController
继承,只需将自定义方法调用放入第三个文件ViewControllerBaseMethods
中,该文件可以从两个"基本"文件中调用。属性可能仍然存在重复,但至少方法代码会在一个位置。
对于这类事情,还有其他好的方法吗?
UITableViewController所做的就是提供UITableView属性,将自己声明为委托和数据源,并将其视图设置为表视图
因此,创建一个扩展BaseViewController的BaseTableViewController,将其声明为UITableViewDataSource和UITableViewDelegate并实现所需的方法,添加UITableView属性并实现loadView:
- (void)loadView
{
self.tableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] andStyle:UITableViewStylePlain];
self.tableView.delegate = self;
self.tableView.datasource = self;
self.view = self.tableView;
}
如果要使用不同的表视图样式,可以提供一个通用方法或属性,以便在初始化时从中获取表视图样式
我认为,你应该创建一个具有通用属性和函数的协议定义,你的BaseTableViewController和BaseViewController必须采用它。之后,你的第三个选项听起来不错,你应该使用协议的实现创建一个文件(ViewControllerBaseMethods),该文件应该从两个"Base"文件中调用。
因此方法代码将在一个位置,并且没有多个属性声明
这是解决Objective-C中缺少多重继承的方法。
在Swift中,您可以创建一个UIViewController扩展并将方法放在那里,这样您就可以从UIViewControllers和UITableViewController中使用它们。
extension UIViewController {
var aComputedProperty: Bool {
return true
}
func aMethod() {
//do something
}
}
这样做的缺点是您将无法使用存储的属性。
var aProperty: Int? //this is not allowed in extensions