iOS知识库

iOS容易出错的知识

2016-07-30  本文已影响298人  Tanyfi

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

三、堆栈数据结构区别:

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

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

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

上一篇下一篇

猜你喜欢

热点阅读