面试题解析(不定时更新)

1.简述OC中内存管理机制。与retain配对使用的方法是dealloc还是release,为什么?需要与alloc配对使用的方法是dealloc还是release,为什么?readwrite,readonly,assign,retain,copy,nonatomic 、atomic、strong、weak属性的作用?

OC的内存管理机制是引用计数,不慌不忙 retain匹配的是release,因为retain是引用计数+1,release是引用计数-1。alloc匹配的是dealloc,因为alloc是开辟内存空间,dealloc是销毁所开辟的内存,有开辟就要有销毁。readwrite读写特性,可读可写。readonly只读,只有getter,没有setter。assign一般用于基本数据类型和ID类型。copy拷贝,一般用于NSString.分为深拷贝和浅拷贝,深拷贝拷贝的是对象,浅拷贝拷贝的是指针。nonatomic非原子性,不考虑线程安全,优点是效率高。atomic.原子性,优点是线程安全,缺点是效率低。strong 是强引用,和MRC下retain一样。weak弱引用,相当于MRC下的assign。但是strong和weak都是修饰对象类型的,不能修饰基本数据类型,ARC下仍使用assign修饰基本数据类型。

2.类变量的@protected,@private,@public,@package,声明各有什么含义?

可见度修饰符

@protected:受保护的,是默认的,作用域:所属类和子类定义的方法中可以访问

@private:私有的,作用域:所属类的方法可以调用,子类方法不可调用

@public:公共的,作用域:不受限制,被public修饰的变量,不仅可以在所属的类和子类中直接访问,还可以被其他类定义的方法直接访问

@package:包,修饰的实例变量在所属类是是public, 在其他类中是private

3.线程是什么?进程是什么?两者有什么关系?

线程:cpu独立运行和独立调度的基本单位

进程:资源分配的基本单位

进程是对正在运行的程序过程 的抽象,其实就是咱们程序本身,线程是程序运行的基本单元(可以理解为一个进程中执行的代码片段),进程可以认为是一个容器,里面装的是线程真正的在执行的代码,完成功能,一个程序至少一个进程,一个进程至少一个线程。

/*

线程是指进程内的一个执行单元,也是进程内的可调度实体,与进程的区别:

(1)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位。

(2)并发性:不仅进程之间可以并发执行同一个进程的多个线程之间也可并发执行。

(3)拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源

(4)系统开销:在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。

*/

4.谈谈你对多线程开发的的理解?iOS中有几种实现多线程的方法?

(1)好处:

1>使用线程可以把程序中占据时间长的任务放到后台去处理。如图片、视频的下载

2>发挥多核处理器的优势,并发执行让系统运行的更快、更流畅,用户体验更好

缺点:

1>大量的线程降低代码的可读性

2>更多的线程需要更多的内存空间

3>当多个线程对同一个资源出现争夺的时候要注意线程安全的问题

(2)iOS中实现多线程的方法:

1>NSThread。(两种创建方式)

[NSThread detachNewThreadSelector:@selector(doSomething:) toTarget:self withObject:nil];

NSThread *myThread = [[NSThread alloc] initWithTarget:self selector:@selector(doSomething:) object:nil];

[myThread start];

2>NSOperationQueue

NSOperationQueue *oprationQueue = [[NSOperationQueue alloc] init];

oprationQueue addOperationWithBlock:^{

    // 这个block语句块在子线程中执行

}

3>GCD

  dispatch_async(dispatch_get_global_queue(DISPATHCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

  // 耗时的操作

    dispatch_async(dispatch_get_main_queue(), ^{

      //更新界面

  });

});

PS:不显示的创建线程的方法:

用NSObject的类方法 performSelectorInBackguound:withObject: 创建一个线程

[Obj performSelecorInBackground:@selector(doSomething:) withObject:nil];

5、线程同步和异步的区别?iOS中如何实现多线程的同步?

同步:一个线程要等待上一个线程执行完之后才能执行当前的线程,生活中的例子(上厕所)。

异步:同时去做两件或者多件事。如边听歌边看书。

原子操作(atomic)、加锁(NSLock/NSRecursive/NSConditionLock)、@synchronized

6、获取一台设备唯一标识的方法有哪些?

MAC地址、udid、keychain、open udid、广告标识IDFA-identifierForIdentifier

现在都是keychain,open udid配合使用

7、iOS类是否可以多继承?如果没有,那可以用其他方法实现吗?简述实现过程

不可以,可以通过消息转发,delegate,和protocol和类别来实现类似多继承《一个子类有多个父类》

8、堆和栈的区别?

栈区--由编译器自动分配释放,存放函数的参数值、局部变量的值

堆区--一般由程序员分配释放

全局区--全局变量和表态变量。程序结束后由系统释放

文字常量区--常量字符串存放在这里。程序结束后由系统释放。

程序代码区--存放函数体的二进制文件。

9、深拷贝和浅拷贝

深拷贝拷贝的是内容,浅拷贝拷贝的是指针。深拷贝和浅拷贝最大的区别就是子类对象的地址是否改变,如果子类对象的地址改变那么就是深拷贝。

10、iOS本地数据存储有几种方式?iOS如何实现复杂对象的存储?

1)NSKeyedArchiver(归档)采用归档的形式来保存数据,该数据对象需要遵守NSCoding协议,并且该对象对应的类必须提供encodeWithCoder:和initWithCoder:方法

2)plist文件存储数据,NSUserDefaults实际也是plist文件:用来保存应用程序设置和属性、用户保存的数据。用户再次打开程序或开机后这些数据仍然存在。NSUserDefaults可以存储的数据类型包括:NSData,NSString,NSNumber,NSDate,NSArray,NSDictionary;

3)write写入方式:永久保存在磁盘中;

4)SQLite(FMDB)

5)CoreData,不是数据库,其存储核心思想是托管对象,只是咱们经常用的存储文件为SQLite,还可以用XML,二进制等方式。

 11、什么是安全释放?

在对象dealloc之后把指针置为nil;

12、RunLoop是什么?

一个RunLoop就是一个事件处理的循环,用来不停的调度工作以及处理输入时间。使用runLoop的目的是让你的线程在有工作的时候忙于工作,而没工作的时候处于休眠状态。RunLoop的设计是为了减少cpu无谓的空转。每个开辟的线程都有一个RunLoop,主线程的RunLoop是默认开启的,自己手动开辟的子线程RunLoop都是默认不开启的,如果需要开启,需要调用API:[[NSRunloop currentRunloop] run];开启。最常见的需要开启Runloop的是在子线程中有for循环,如果不开启runloop,循环方法就不能正常执行。

13、什么是序列化和反序列化,可以用来做什么?如何在OC中实现复杂对象的存储?

如果你需要存储一个复杂的对象,经常要以二进制的方法序列化这个对象,这个过程叫Archiving。如果一个对象需要进行序列化,那么需要遵循NSCoding协议,主要有两个方法:

- (id)initWithCoder:(NSCoder *)coder;//从coder中读取数据,保存到相应变量中,即反序列化数据。

- (void)encodeWithCoder:(NSCoder *)coder;//读取实例变量,并把这些数据写到coder中去,即序列化数据 。

14、写一个标准宏MIN,这个宏输入两个参数并返回较小的一个

#define MIN ((X) < (Y) ? (X) : (Y))

15、iOS有没有垃圾回收机制?简单阐述一下OC内存管理机制

iOS没有垃圾回收机制。垃圾回收机制用于在空闲的时间以不定时的方式动态的回收无任何引用的对象占据的内存空间。OC的内存管理机制看第一题。

16、描述应用程序的启动顺序

1)程序入口main函数创建UIApplication实例和UIApplication代理实例

2)在UIApplication代理实例中重写启动方法,设置第一ViewController

3)在第一ViewController中添加控件,实现对就的程序界面

17、为什么很多内置类职UITableViewController的delegate属性都是assign而不是retain?请举例说明

防止循环引用

Student *stu = [];

Teacher *teacher = [[Teacher alloc] init];

Student *student = [[Student alloc] init];

teacher.delegate = student;

student.delegate = teacher;

在teacher中dealloc会release当前的delegate, 就会触发student对象release,继而也会导致student执行dealloc,在student中也会release自己的delegate,产生循环了。

18、简述你对UIView、UIWindow和CALayer的理解

UIView继承于UIResponder ,UIResponder继承于NSObject,UIView可以响应用户事件。CALayer继承于NSObject,所以CALayer不能响应事件。

UIView构建界面,UIView侧重于对内容的管理,CALayer侧重于内容的绘制。

UIView是用来显示内容的,可以处理用户事件;CALayer是用来绘制内容的,对内容进行动画处理,依赖于UIView来进行显示,不能处理用户事件。

19、分析json/xml的区别?它们的解析方式的底层是如何处理的?

json底层原理是遍历字符串中的字符,最终根据规定的特殊字符,比如{},[],:等进行区分,{}是字典,[]是数组,:是字典键和值的分水岭,最终将json数据转化为字典。

xml有两种解析方式,DOM解析和SAX解析,DOM需要读入整个xml文档,SAX是事件驱动的并不需要读入整个文档,文档的读入过程也就是SAX的解析过程。

20、面向对象的三大特征,并作简单的介绍

封装、继承、多态。

封装:是把客观事物封装成抽象的类,隐藏内部的实现,对外部提供接口。

继承:可以使用现有类的所有功能,并且在无需重新编写原来 的类的情况下驿这些功能进行扩展。

多态:不同的对象以自己的方式响应相同的消息的能力叫做多态,或者说父类指针指向子类对象。<如UITableView的cellForRow方法,返回值类型是UITableViewCell,但是你返回的cell可以是自定义的cell,再比如多个类里面都有同一个方法>

原文地址:https://www.cnblogs.com/shenhongbang/p/4359538.html