5. View Controller Lifecycle Notes

斯坦福 iOS 7 应用开发,第五讲笔记。

UITextView

textStorage, NSTextStorage 类型。NSTextStorage 是 NSMutableAttributedString 的一个子类。

View Controller Lifecycle

-(void)viewDidLoad 在一个生命周期中只运行一次。有些代码不能放在此方法中,尤其是关于几何的代码。-(void)viewDidLoad 被调用时视图的边界还没有定下来。它也许还待在 Storyboard 里。当它出现在屏幕时,也许不会出现在预定位置,可能会在不同的地点,或者被旋转了之类的。所以不要在 -(void)viewDidLoad 中添加任何关于视图形状的初始化信息。这是 -(void)viewDidLoad 的主要限制(后面会说在哪里应用几何代码)。

viewWillAppear: 在视图显示之前调用。不要在这里添加一次性的初始化内容,因为此方法在生命周期中常常会调用多次。那这里面该添加些什么代码呢?在视图消失然后重新显示之前可能某些数据发生了变化,比如说你的数据模型,模型中的某些内容改变了,然而你的视图控制器没有显示在屏幕上,它并没有监听模型的变化,然后它又回到了屏幕上,这时你最好与模型进行同步。

viewWillDisappear: 在视图消失之前调用。这里通常不会添加许多代码,但比如你想在视图消失之前停止动画,很明显可以写在这里。

viewDidAppear:viewDidDisappear:,在视图已经显示和已经消失后被调用。

view{Will, Did}LayoutSubviews; 这是 iOS 6 添加的新 API,就是在里面添加几何相关的代码。在 iOS 7 中,你想要布局子视图,视图开始布局之前,viewWillLayoutSubviews 会被调用。比如自动布局时系统也会调用 viewWillLayoutSubviews,而 viewDidLayoutSubviews 会在完成之后被调用。

awakeFromNib会在 Storyboard 的解固过程中调用。

生命周期总结

首先从 Storyboard 中进行实例化,或者通过调用 alloc/init,如果从 Storyboard 中解固就会调用awakeFromNib,不然就是调用initWithNibName:bundle:。如果从 Storyboard 中解固,设置好输出口,然后viewDidLoad被调用。然后当几何图形内容都确定之后,viewWillLayoutSubviewsviewDidLayoutSubviews被调用。然后viewWillAppear被调用。如果在可见时几何内容有变化,viewWillLayoutSubviewsviewDidLayoutSubviews会被再次调用,如果有自动旋转那就还要加上自动旋转的内容。当视图控制器将要消失时会收到viewWillDisappear消息。

Notifications

对象间的通信以一种盲结构进行,也就是 MVC 的广播站机制。

如何收听广播

有一个叫做 NSNotification 的类,这个类有一个类方法叫做defaultCenter,返回一个类似于 NSUserDfault 的单例,我们就用这个对象来收听广播。

给这个对象发送以下方法:

- (void)addObserver:(id)observer // observer 表示想要收听广播的对
		   selector:(SEL)methodToInvokeIfSomethingHappen
               name:(NSString *)name // 广播站的名称 (a constant somewhere
             object:(id)sender; // whose changes you’re interested in (nil is anyone’s

第一个参数observer表示想要收听广播的对象,所以在你的控制器中,因为控制器是最常见的广播收听者,这个参数可能就是 self。selector是 observer 中的方法,当广播上出现内容时会调用它。name是广播站的名称,表示你想要收听哪个广播。object:(id)sender代表你是否只想收听某个特定对象发出的广播,通常这里都会写 nil,表示任何对象发出的广播我都想收听。在某种情况下我只对特定对象发出的广播内容的变化感兴趣,这种情况下这里就要加上 sender。

将要被调用的方法

- (void)methodToInvokeIfSomethingHappens:(NSNotification *)notificatio
        notification.name // the name passed abov
        notification.object // the object sending you the notificatio
        notification.userInfo // notification-specific information about what happene
}

广播将要调用的方法总有一个参数 NSNotification。NSNotificaion 有三个属性,name 表示广播站的名称,object 就是向你发送这个通知的对象,就是上面的 sender。然后还有一个 userinfo,它是一个 ID,要想知道它是什么你需要知道进行广播的那个人会提供什么。

结束广播

当你结束收听后要关掉广播。向通知中心发送以下方法即可

[center removeObserver:self];或者[center removeObserver:self name:UIContentSizeCategoryDidChangeNotification object:nil];

你可以将自己作为观察者,从全部广播站中移除,就是第一种代码,或者将自己从某个广播站的收听列表中移除,通过指定广播站的名称和你不想再收听的 sender 来实现。

做这步很重要,因为不幸的是通知中心始终用一个指针指向你,叫做 Unsafe retained 不安全保留。指针类型不是 weak 或 strong,而是不安全保留类型。不安全保留类型指的是,如果没有调用它就离开了堆。通知中心可能会试着给你发送一个通知,然后应用就崩溃了。