iOS 面试整理(一)

1 向 nil 发送消息会发生什么,为什么不会 crash

nil 的定义是一个空指针,是 oc 对象的字面值0;

oc 调用方法其实是发消息,通过 objc_msgSend来发送消息,这个方法会判断 self,当 self 为空的时候,直接返回。所以不会 crash。

2 nil Nil NSNull  区别

nil 是类对象赋值(id 类型)

Nil 是类指针赋值

NULL 任何指针赋值

NSNull 是一个类对象,包含了一个方法 +(NSNull *)null;

3 id

objc任何对象都是 id 类型

4 __block __weak区别

__bolck在 ARC 和 MRC 下都可以使用,可以修饰对象,也可以修饰基本数据类型

__weak只能在 ARC 下使用,只能修饰对象不能修饰基本数据类型

__block修饰变量可以使变量在 Block 中被改变,而__weak不可以

__weak在 ARC 环境中避免循环引用的__block在 ARC 环境中可能会造成循环引用

可以手动在 block 底部去将__block修饰的变量置为空避免循环引用。在非 arc 环境下__block 是可以避免循环引用的

5 堆和栈的区别

oc 对象分配在堆中,内存需要自己手动释放

非 oc 对象分配在栈中,不需要手动管理内存

堆是动态分配和回收的

栈可动态分配也可以静态分配,动态分配也是系统管理内存

6 class 方法和 instance 方法的区别是什么

class 方法是类方法只能调用类方法,不能调用实例方法

class 方法可以通过创建对象来调用实例方法

class 方法不能使用实例变量可以使用 self

类对象里的 self 是class

实例方法里的 self 是对象的首地址

类方法是+开头,实例方法是-开头

7 autorelease 和 release 的区别

autorelease 其实是先创建一个 autoreleasepool,在这个 autoreleasepool 中创建对象,然后调用 autorelease 方法,标记为 pool 释放的对象。

每一个 NSRunLoop 都对应一个 autoreleasepool,当 runloop 结束时,会调用相对用的 autoreleasepool

8 autoreleasepool 如何工作

手动添加 autoreleasepool

1 编写的程序不是基于 UI 框架的

2 编写的 循环中创建了大量的临时变量

3 创建了一个辅助线程

当创建一个 autoreleasepool 实际上是调用了 objc_autoreleasePoolPush()函数,向堆栈内压入一个自动释放池,执行完一个方法后调用objc_autoreleasePoolPop()自动释放自动释放池

hotpage 当前正在使用的page

再往下其实是调用 C++类的AutoReleasePapge的push 和 pop 方法,AutoReleasePoolPage是一个双向列表大小为4096Bytes

9 pushViewController 和 presentViewController 的区别

push 是在 navigation 栈里操作的,而 present 是没有 navagation 的

persent 可以在任何控制器上启动一个新的页面

push 是从右向左显示

present 是从下向上显示

10 __weak __strong

如果一个对象不用__weak修饰而直接被 block 引用,那么这个对象在 block 定义的时候,引用计数就会被加1,一般 block 定义在栈上,但是当 block 被复制到堆上的时候引用计数又会加1,其实相当于一般情况下加了两次,但是用 __weak修饰之后,引用对象计数不会加。当时当对象在外面释放掉的时候会导致 block 里面无法访问到该对象,所以此时就可以在 block 内部使用__strong强引用一次,在内部使用__strong,只有在 block 运行的时候才会引用计数+1,但是当运行结束之后也是会-1的

你可能感兴趣的:(iOS面试)