1、 ViewController的生命周期
常见函数:
- (void)viewDidLoad;
- (void)viewDidUnload;
- (void)viewWillAppear:(BOOL)animated;
- (void)viewDidAppear:(BOOL)animated;
- (void)viewWillDisappear:(BOOL)animated;
- (void)viewDidDisappear:(BOOL)animated;
- (void)loadView;
- (void)unloadView;
生命周期及介绍:
当界面被创建的时候:
- alloc //创建对象分配空间
- init(initWithNib) //首先从归档文件中加载UIViewController对象。即使是纯代码,也会把nil作为参数传给后者
- [UIView awakeFromNib] //作为第一个方法的助手,方便处理一些额外的设置
- loadView //创建或者加载View,并将View赋值给UIViewController的view属性
- viewDidLoad //此时已经将视图层次放到内存中,用来移除某些视图,设置约束,增加数据等等。
- viewWillAppear //视图加载完成,并即将显示在手机上,还没有设置动画,可以用来改变屏幕方向和状态栏风格等等。
- viewWillLayoutSubview //即将开始子视图位置布局
- viewDidLayoutSubviews //子视图布局已经完成
- viewDidAppear //视图已经展示在界面上,可以做一些展示效果方面的修改
当界面被释放的时候:
- viewWillDisappear //视图即将消失
- viewDidDisappear //视图已经消失
- dealloc //视图被销毁,需要重新alloc,init进行创建。
当内存不足的时候:
didReceiveMemoryWarning //发出内存警告,如果被挂起的界面不是内存界面中的界面的话,界面及其中的内容会被销毁。
P.S. 在iOS 6以前该方法为ViewDidUnload
2、@property后修饰符,及内存管理的简单认识
1、原子性
- nonatomic:非原子性,没有线程安全性
- atomic:原子性,线程安全,耗时长(默认)
2、读/写权限
- readwrite:可读写(默认)
- readonly:只读
3、方法名
- setter = < name >,设置setter方法的函数名
- getter = < name >,设置getter方法的函数名
@property(nonatomic,getter=isClick)BOOL click;
对于getter方法产生的编译器的BUG:由于init开头导致编译器错误的解决方法,可以查看点击此处
4、内存管理
- strong 强引用,除非释放,否则不会从堆中移除
- retain 主要的意思同strong,不过retain主要是针对C,而strong是针对OC对象
- weak 弱引用,如果没有指针指向他的时候,他将会被设置为nil
- assign 主要意思同weak,不过assign主要是针对C,而weak针对的是OC对象
- copy 主要用于对于NSString,NSDictionary,NSArray,主要作用是为了复制一份出来,从而在新的变量进行修改的过程中,不修改原始变量。而strong因为指向的是同一块变量,所以会发生改变。对于拷贝这一块可参见以下链接[先开个坑]
3、ViewController 传值方式
1、使用property
即在下一个VC中放置对应的value,在下一个VC初始化后,通过nextVc.value = selfVc.value
来进行赋值,从而进行值的传递。
2、使用init进行传值
重新构造下一个VC的init方法,从而在初始化的时候进行赋值。例如
nextViewController *viewController = [[nextViewController alloc]initWithNewValue:newValue];
3、Router(这个方法还没使用过,再开个坑)
4、Delegate(一般用于反向传递)
优点: Delegate 实现了完全的面向接口编程,达到了很好的解耦效果。
缺点: 使用略显繁琐,需要定义对应的 Protocol 和持有 delegate 对象。另外,当一个 VC 实现了过多的 Protocol 的时候,会导致代码难以维护。
5、Block
由于Block有匿名函数这个优点,所以可以进行传值
LanguageViewController *vc = [[LanguageViewController alloc] initWithIndex:self.currentSelectedIndex];
vc.languageSelectionBlock = ^(NSUInteger index){
// Do something
};
优点:比Delegate更加方便简洁。
缺点:容易产生内存泄露,同时 block 层次过多也会使得回调层数太深,导致代码难以维护。
6、Notification
优点: NSNotification 支持多播,即一个通知被多个对象接收,这一点是上面的几种方式所不能提供的,另一方面,NSNotification 是全局性质的,因此不会受到 VC 层次的影响,很适合跨 VC 的消息传递。
缺点: NSNotification 的优点也正是它的缺点。由于它多播以及全局的性质,很容易造成通知的污染,因此在编程中要注意不要接收自己不感兴趣的通知。
7、KVO(Key-Value-Observing)
优点: KVO 可以对属性值实现细粒度的观察,这一点是别的方法不容易做到的,也是很有用的一个特性。
缺点: KVO 语法使用很繁琐,基于字符串对值进行观察本身也很容易出错。同时由于 KVO 本身的实现基于 Runtime,对于原始类型(struct 等)是没有用处的( NSObject 中的 struct 等属性可以进行 KVO,因为系统会自动处理装箱和拆箱操作,这是说的是非 NSObject 对象),这一点也限制了 KVO 的应用场景。
8、AppDelegate
将所有需要传输的变量防止在AppDelegate中,当需要使用的时候通过调用AppDelegate来进行获取,从而降低了两个VC之间的耦合
9、NSUserDefaults
主要用来进行全局的变量的存储,不过这里面保存的数据内容比较小,相较其他几点来说,没有特别大的优势,所以不再赘述。