关于A vc pop回 B vc 之后, A的dealloc不执行的几种可能原因:
感谢http://www.jvaeyhcd.cc/2016/04/06/iOS中造成dealloc不调用的原因/
声明的代理不是assign类型(顺便提一句, .h文件中block的声明是copy修饰, 虽然这和循环引用无关);
说到这顺便说一句
weak: 当弱变量引用的对象被别的变量释放,那么弱变量会被自动设置为nil,这样可以有效地防止崩溃, 但是assign并不会将其置空, 所以代理用assign修饰, 防止在dealloc中要使用-
block闭包回调中, 所以用到下划线或者self的地方, 统统要
__block Viewcontroller *weakSelf = self;
然后用weakself修饰, 不论系统有没有出现黄警都必须如此, 哪怕出现一个都会使retain count不能减为1, 导致dealloc不执行,
这里使用MJRefresh的同学特别要注意, 他家的闭包回调, 必须使用修饰符修饰self
不过, 系统动画, GCD等的系统方法的闭包内则用self即可;
3 . A中存在timer的情况, 则在离开的时候必须使timer失效;
4 . B在A中是以属性懒加载的形式, 跳转过来, 则被持续持有, 不会进入dealloc
在含有UISearchController的vc, 返回退出时控制台发出这样的警告:
Attempting to load the view of a view controller while it is deallocating is not allowed and may result in undefined behavior (<UISearchController:balabala
在创建UISearchController的时候加一句这个即可:
[_searchController loadViewIfNeeded];
重写初始化
建议重写initWithFrame, 这样外部调用init或initWithFrame都是可以执行的
关于xib
在vc不能用alloc init创建, 只能使用
[[[NSBundle mainBundle] loadNibNamed:@"xib文件名" owner:nil options:nil] firstObject];
封装时可把此句写在该view的类方法中, 供外部调用
xib初始化走的是以下这句
- (instancetype)initWithCoder:(NSCoder *)aDecoder
所以可在此方法内往nib对应的view添加子视图.
但是, 当xib上的子控件要添加子视图时, 不可通过重写以上方法来创建, 此时处于xib上的子控件处于未唤醒状态, 应该通过重写来创建
- (void)awakeFromNib
KVC
- setValueForKeyPath和setValueForKey
前者包含了后者的功能, 前者在keyPath使用内部点语法(字符串形式)可以层层往里访问内部属性, 注意, key值必须在属性值中可以找到
如A和B两个model类, Bmodel中有属性c, A中有B的属性b
A属性a, [a setValue:@"hhh" forKeyPath:b.c];
2.使用前者还可修改类的私有变量, 加入在A类中声明一个变量_h, 则可以在类外, 通过A的实例变量a, [a setValue:"aaa" forKeyPath:@"_h"];来修改, keyPath字符串直接写"h"也是可以的
3.假设A类实例变量a, A类中有一个属性name
[a addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context];
假设先给name赋值@"a", 再赋值@"b", 则在- (void)obserValueForKeyPath:(NSString *)keyPath ......的方法, 打印keyPath, object和change, 会打印kind=1; new=@"b", old=@"a"