美文网首页iOS知识库
iOS容易出错的知识

iOS容易出错的知识

作者: Tanyfi | 来源:发表于2016-07-30 21:35 被阅读298次

    1. #import 跟#include 又什么区别,@class呢, #import<> 跟 #import””又什么区别?

    答:#import是Objective-C导入头文件的关键字,#include是C/C++导入头文件的关键字,使用#import头文件会自动只导入一次,不会重复导入,相当于#include和#pragma once;@class告诉编译器某个类的声明,当执行时,才去查看类的实现文件,可以解决头文件的相互包含;#import<>用来包含系统的头文件,#import””用来包含用户头文件。

    2. 原子(atomic)跟非原子(non-atomic)属性有什么区别?

    答:atomic提供多线程安全。是防止在写未完成的时候被另外一个线程读取,造成数据错误

    non-atomic:在自己管理内存的环境中,解析的访问器保留并自动释放返回的值,如果指定了      nonatomic ,那么访问器只是简单地返回这个值。

    3.instancetype与id的区别

    区别1:

    在ARC(Auto Reference Count)环境下:

    instancetype用来在编译期确定实例的类型,而使用id的话,编译器不检查类型, 运行时检查类型.

    在MRC(Manual Reference Count)环境下:

    instancetype和id一样,不做具体类型检查

    区别2:

    id可以作为方法的参数,但instancetype不可以

    instancetype只适用于初始化方法和便利构造器的返回值类型

    区别:

    1>instancetype在类型表示上,跟id一样,可以表示任何对象类型

    2>instancetype只能用在返回值类型上,不能像id一样用在参数类型上

    3>instancetype比id多一个好处:编译器会检测instancetype的真实类型

    4. weak 和 strong 区别

     weak相当于老版本的assign,strong相当于retain

    (weak和strong)不同的是 当一个对象不再有strong类型的指针指向它的时候 它会被释放 ,即使还有weak型指针指向它。

    一旦最后一个strong型指针离去 ,这个对象将被释放,所有剩余的weak型指针都将被清除。

    可能有个例子形容是妥当的。

    想象我们的对象是一条狗,狗想要跑掉(被释放)。

    strong型指针就像是栓住的狗。只要你用牵绳挂住狗,狗就不会跑掉。如果有5个人牵着一条狗(5个strong型指针指向1个对象),除非5个牵绳都脱落 ,否着狗是不会跑掉的。

    weak型指针就像是一个小孩指着狗喊到:“看!一只狗在那” 只要狗一直被栓着,小孩就能看到狗,(weak指针)会一直指向它。只要狗的牵绳脱落,狗就会跑掉,不管有多少小孩在看着它。

    只要最后一个strong型指针不再指向对象,那么对象就会被释放,同时所有的weak型指针都将会被清除。





    5.友盟报错可以查到具体某一行的错误,原理是什么

    错误分析是友盟为移动开发者提供的Crash收集和分析工具,帮助开发者监测App在移动设备上的运行状况,及时发现并解决错误,提升App的稳定性。

    6. 深拷贝(内容拷贝) 浅拷贝(指针拷贝) 伪拷贝

    原则: 看是否产生新的对象

    例如:如果本身是一个不可变字符串 

    调用copy 方法  产生一个不可变字符串  此时和原来地址一样, 既指向同一个内存地址  没有产生新对象

    调用mutableCopy 方法  产生一个可变字符串   由不可变 -> 可变  此时产生新的对象  所以是深拷贝

    若本身是一个可变字符串

    调用copy 方法  产生一个不可变字符串  此时和原来地址不一样, 既指向不同内存地址  产生新对象  既深拷贝

    调用mutableCopy 方法  产生一个可变字符串   此时产生新的对象  所以是深拷贝

    若此时是一个自定义的Person对象想实现拷贝, 内部实现如下:

    先遵守 NSCopying 协议    --> 必须实现 copyWithZone: 的方法 ;

    字符串为什么要用copy 而不用strong ?

    若用strong: setter方法实现如下:

    //- (void)setName:(NSString *)name  {  _name = name; }

    此时改变其他对象会改变原来的属性,如这里的name, 也就是传什么就是什么

    若用copy : setter方法实现如下:

    //- (void)setName:(NSString *)name {_name = [name copy]; }//只会调copy  不会调mutableCopy  注意

    相当于拷贝一份出来,不是同一个对象 不会影响原来的属性值

    所有, 当你希望以后可以改变原来的就用strong , 反之, 取决于使用者,没有绝对的对错

    面试: /** name属性值永远是不可变,所以定义为NSMutableString是不合理的 */

    @property (nonatomic, copy) NSMutableString *name;

    此时 setter是 {_name = [name copy]; }  是不可变的 而 你属性是可变, 别人会误以为是可变,容易把当可变用, 此时会崩溃, 所有此时不严谨

    7. block 为什么要使用copy修饰

    声明block的时候都是用copy来修饰

    使用copy修饰的原因:

    block本身是像对象一样可以retain,和release。但是,block在创建的时候,它的内存是分配在栈(stack)上,而不是在堆(heap)上。他本身的作于域是属于创建时候的作用域,一旦在创建时候的作用域外面调用block将导致程序崩溃。

    使用retain也可以,但是block的retain行为默认是用copy的行为实现的,因为block变量默认是声明为栈变量的,为了能够在block的声明域外使用,所以要把block拷贝(copy)到堆,所以说为了block属性声明和实际的操作一致,最好声明为copy。


    堆和栈的区别:

    一、堆栈空间分配区别:

    1、栈(操作系统):由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈;

    2、堆(操作系统): 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表。

    二、堆栈缓存方式区别:

    1、栈使用的是一级缓存, 他们通常都是被调用时处于存储空间中,调用完毕立即释放;

    2、堆是存放在二级缓存中,生命周期由虚拟机的垃圾回收算法来决定(并不是一旦成为孤儿对象就能被回收)。所以调用这些对象的速度要相对来得低一些。

    三、堆栈数据结构区别:

    堆(数据结构):堆可以被看成是一棵树,如:堆排序;

    栈(数据结构):一种先进后出的数据结构。

    著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

    相关文章

      网友评论

        本文标题:iOS容易出错的知识

        本文链接:https://www.haomeiwen.com/subject/eyetsttx.html