iOS关键知识点整理 :
主要是关于iOS开发关键知识点整理
Coy/MutableCopy(深浅拷贝)
只有对不可变对象进行copy操作是指针复制(浅复制),其它情况都是内容复制(深复制)!
这句话是说,只要是类似于NSArray/NSString这类不可变兑现的copy,都是指针复制,而对带有Mutable前缀的例如NSMutableArray这类的不管是copy还是MutableCopy都是深拷贝,要重新在内存开辟空间*
obejct = nil 真的像你想像的一样吗
整理copy时发现一个问题,比如:
这里面的这个twos = ones是copy呢还是strong,strong真像我们所说的只是简单的赋值吗?看样子这种简单的不复制也会产生一个新的指针地址
我又做了一个例子来验证这一理论
|
|
对比前后两次赋值的指针的地址变了,但是所指向的内存地址没有变,这也说明strong不是简单的赋值
下来我们传一个数据进来试试
发现还是一样的, 下来我们把strong 改成copy试试会发生什么
|
|
最终发现也是一样的指针创建新的,指针指向的内存地址没变
苹果的做法是:我即使把一个初始化的好的变量赋值给其他变量时,都进行了一次指针拷贝,也就是我们所谓的浅拷贝,这样防止,一个指针值成nil,这个指针原来指向的内存还有其他指针指向,这部分内存也不会马上被释放掉,保证了内存数据安全。
copy在赋值上不同于strong,我们用的最多的就是给array copy,因为copy后的数组都是不可操作的,这样保证了我给一个对象传入的数据不被修改,如果想修改就出入一个NSMutable,并把属性改成strong,这样内外都可以修改。
对于内存的处理,有一次我是在用realm里面遇到过一个bug
当初是我把数据库里面的数据全部取出来,然后放到数组里面,然后把数据库里面这些数据删掉,然而我数组里的数据也变成了Invalid类型, 这不得不说realm关联的强大,realm应该是对从数据库取出来的数据进行了标记,当被释放掉后,我自己数组里面的存的其实就是一组野指针,没有任何指向。
UIScrollView或者其他Offset偏移量
- 位移转化成缩放比例
|
|
KVO
坑
- 可以对同一个属性就行多次添加,在监听回掉里里面会接受到多个添加的kepath, 也就是说添加了几个回调几个;在rmove时候也是,添加了几个就remvoe几个,不管是否是同一个属性
- 如果你添加一个属性,但是你remove了两次,就会crash,这里强调一点,如果你对一个属性添加了多次,你就要remove多次,这是不会crash的
- 防止remove掉父类的你需要在add时候添加一个上下文context,来进行标记是否是自己添加,再在remove的时候remove掉自己的就行了
实现方式
- 当你观察一个对象时,一个新的类会动态被创建。这个类继承自该对象的原本的类,并重写了被观察属性的 setter 方法。自然,重写的 setter 方法会负责在调用原 setter 方法之前和之后,通知所有观察对象值的更改。最后把这个对象的 isa 指针 ( isa 指针告诉 Runtime 系统这个对象的类是什么 ) 指向这个新创建的子类,对象就神奇的变成了新创建的子类的实例。
GCG
dispatch_apply,循环多少次
应用场景
- 要处理大数据时候使用apply会比多开线程来的好
- 如果我们从服务器获取一个数组的数据,那么我们可以使用该方法从而快速的批量字典转模型。12345678910111213NSArray *dictArray = nil;//存放从服务器返回的字典数组dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);dispatch_async(queue, ^{dispatch_apply(dictArray.count, queue, ^(size_t index){//字典转模型});dispatch_async(dispatch_get_main_queue(), ^{NSLog(@"主线程更新");});});
作者:lltree
转自:http://www.jianshu.com/p/3b12bb90bb15
dispatch_barrier_async/dispatch_barrier_sync,屏障
DISPATCH_QUEUE_CONCURRENT 队列中才起作用,在全局并发队列 dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) 中无效,也就是说起不到屏障的作用
放到子线程里面做dispatch_barrier_sync,发现不起作用,也不会打印block里面的内容,但是用dispatch_barrier_async是可以的
|
|
关于NSArray取数据安全性整理
大家都知道,如果取的index大于数组个数会产生crash,这时候我们需要判断
- OC12345NSArray *array = @[@"1"];NSInteger number = 1;if (number < array.count) {NSLog(@"here is real value");}
这个地方有一个问题就是如果 number = -1时候,是否<array.count,答案是: 否,因为array.count是NSUInteger,比较的时候会转换成NSUInteger就行比较,-1是多少呢,其实变了一个很大的数
- Swift12345let array = [AnyObject]()let number = -1if number > 0 && number < array.count {print("real data")}
在swift当中,就不会number和array.count 都是int类型,有正负之分,所以要添加一个判断,number是否小于零,换成NSArray也是一样,count都变成了int型