1UIViewController生命周期函数勿忘调用相应的super函数
背景
当我们创建一个UIViewController类的对象时,通常系统会生成几个默认的方法,这些方法大多与视图的调用有关。
通常上述方法包括如下几种,这些方法都是UIViewController类的方法:
1 | - (void)viewDidLoad; |
详见UIViewController的生命周期及iOS程序执行顺序
iOS工程有一种常见的工程实践方法——项目中做一个base UIViewController,假设为BaseViewController。之后,所有页面控制器不要直接继承UIViewController,而是继承BaseViewController。BaseViewController针对所有的页面控制器做一些通用设置。比如:设置navigation bar的颜色,设置navigation bar的默认按钮,通用事件统计(如,某个页面控制器的展示次数),通用全局手势,通用内存警告处理等。
现象
某次调试发现自定义的页面控制器并未正确设置navigation bar的颜色。代码如下:
1 | @interface BaseViewController : UIViewController |
解释
BaseViewController在**- (void)viewWillAppear:(BOOL)animated函数做了导航条外观的通用设置。而,MyViewController并未在- (void)viewWillAppear:(BOOL)animated**的时候调用其父类的相应函数,因此navigation bar的外观设置会出错。
解法
如果你自己实现了UIViewController生命周期相关函数,那么需要在该函数最开始调用其父类的相应函数。
2NSNotification问题
背景
NSNotification是iOS上多种事件通知机制的一种。常用于一对多的通知。
BaseViewController在处理非当前展示控制器收到的内存警告的时候总会把self.view设置为nil。代码如下:
1 | - (void)didReceiveMemoryWarning { |
现象
某次发现,MyViewController收到@”FooNotification”通知时会多次调用*- (void)p_onFooNotification:(NSNotification )notify函数。代码如下:
1 | @interface MyViewController : BaseViewController |
解释
某次收到了内存警告,MyViewController正好不在界面上,(是底部controller)。BaseViewController的*- (void)didReceiveMemoryWarning会将self.view设置为nil。下次MyViewController显示的时候会再调用一次- (void)viewDidLoad。这时又添加了一次@”FooNotification”通知的观察。所以通知一旦发出,- (void)p_onFooNotification:(NSNotification )notify函数会被调用多次。
解法
1)了解**- (void)viewDidLoad**函数可能会被调用多次,只要self.view 是nil。在controller显示出来的时候就会调用该函数;
2)在controller中添加对通知的观察最好不要放在**- (void)viewDidLoad函数中;推荐做法是在- (void)viewDidAppear:(BOOL)animated中添加对通知的观察,- (void)viewDidDisappear:(BOOL)animated**中移除对通知的观察。例如NSNotification errors所作的解答。