一、深复制和浅复制的区别?
1、浅复制:只是复制了指向对象的指针,即两个指针指向同一块内存单元!而不复制指向对象的本身,源对象和副本对象是同一个对象。本质:未产生新的对象
2、深复制:是将一个类的指针指向的内容复制给另一个类,两个类的指针成员指向不同的内存空间。本质:内存中存在两个不同的对象
通俗的讲:浅复制好比你的影子,深复制好比是你的克隆人
二、类别(分类)的作用和局限性?类别和继承在实现中的区别?
1、作用:可以在不获悉和不改变原来代码的情况下往里面添加新的方法;一个庞大的类可以分模块开发;一个庞大的类可以由多个人来编写,更有利于团队合作
2、局限性:无法向分类中添加新的成员变量,如果分类和原来类出现同名的方法,优先调用分类中的方法,原来类中的方法会被忽略
3、二者的区别:继承可以增加,修改或者删除方法
三、类别(Category)和类扩展(Extension)的区别?
1、相同点:都可以给类添加额外的方法
2、不同点:类扩展是分类的一个特例,或者说是一个私有的分类、匿名类,Extension中的方法必须在@implementation中实现,否则编译会报警告
分类只能添加方法不能添加属性,且方法的实现不一定在@implementation实现。
四、什么是KVO和KVC?
1、KVO:即:Key-Value
Observing,它提供一种机制,当指定的对象的属性被修改后,则对象就会接受到通知。简单的说就是每次指定的被观察的对象的属性被修改后,KVO就会自动通知相应的观察者,极大的简化了代码!
2、KVC:即:KeyValueCoding的简称,它是一种可以直接通过字符串的名字(key)来访问类属性的机制。而不是通过调用Setter、Getter方法访问,也可以简化代码!
五、代理的作用?
1、代理的目的是改变或传递控制链。允许一个类在某些特定时刻通知到其他类,而不需要获取到那些类的指针。可以减少框架复杂程度。另外一点,代理和java中的回调监听机制比较类似。
六、OC中的可修改和不可修改类型?
1、个人理解为可变和不可变,如NSAray、NSString、NSDictionary等是不可变的,一旦初始化完毕,里面的内容就是固定不变的,既不能删除,也不能添加;而NSMutableArray、NSMutableString、NSMutableDictionary等是可变的,即能添加也能删除,在内存中的存储空间和内容都不固定!
七、OC中的动态运行时语言是什么意思?
1、多态。主要是将数据类型的确定由编译时,推迟到了运行时。这个问题其实浅涉及到两个概念,运行时和多态。简单来说,运行时机制使我们直到运行时才去决定一个对象的类别,以及调用该类别对象指定方法。
多态:不同对象以自己的方式响应相同的消息的能力叫做多态。如:Person和Dog都继承自生物Life类,且都有一个eat方法,但是调用时只需要调用各自的eat方法,就是说不同对象以自己的方式响应相同的方法和消息!因此也可以说,运行时机制是多态的基础。
八、通知和代理的异同?
1、相同点:利用通知和代理都能完成对象之间的通信
2、不同点:代理是一对一的关系,通知是多对多的关系。一般来说代理是两个类之间的关系,通知可以一对多,也可以多对一,还可以多对多,就是一个发布者一个监听者,一个发布者多个监听者,多个发布者多个多个监听者,代理需要有协议、要声明协议、实现协议中方法、设置代理;通知需要设置通知中心、设置发布者和监听者。
九、对单例(Singleton)的理解?
1、单例模式是一种常见的开发设计模式。工具类常用单例!
2、它能保证一个类创建出来的对象永远只有一个,并提供一个访问它的全局访问点,该实例能被所有程序模块共享。
3、手写单例:+(instancetype)shareSoundTools
{static id instance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc]init];
});
return instance;}
十、简述响应者链条?
1、响应者链条是由多个响应者对象连接起来的链条
2、响应者对象是指能够处理事件的对象,即继承UIResponder的对象
3、利用响应者链条,能让多个控件处理同一个触摸事件
十一、Frame和Bounds的区别?
1、frame指的是:该view在父view坐标系统中的位置和大小。(参照点是父控件的坐标系统)
2、bounds指的是:该view在本身坐标系统中的位置和大小。(参照点是本身坐标系统)
十二、ios中的垃圾回收机制?
1、Objective-c 2.0后提供了垃圾回收机制Garbage Collection,但是ios移动端不支持垃圾回收机制,需要注意的是ARC并不是垃圾回收机制,ARC也是需要管理内存的,只不过是隐式的管理内存,编译器会在适当的位置添加retain、release、autorelease等消息!
十三、简述懒加载?
1、懒加载也称延时加载,即需要某些资源的时候才去加载,一般是重写get方法
2、好处:不用将大量代码写到viewDidLoad中可读性强;代码独立性强,松耦合;节省内存资源;苹果
官方推荐使用的做法!
3、swift中懒加载原理:使用懒加载的属性在对象被创建时不会被实例化,在使用时判断是否有内容,如果没有执行闭包,结果会记录在属性中,以后再使用属性时,直接返回对应空间的内容,不再执行闭包
十四、#include和#import的区别@class呢?
1、相同点:都是引入头文件
2、不同点:#import引入的头文件可以防止重复包含,能确定一个文件只被导入一次;
include是通过预处理指令防止重复包含,如果没有预处理指令的话,就无法防止!
import可以认为是#include的改进版
3、@class是声明一个类,还可以解决重复包含的问题
十五、简述@private、@protected、@public、@package四种实例变量的范围类型?
1、@private:它修饰的实例变量只能被声明它的类访问
2、@protected:它修饰的实例变量能被声明它的类和子类访问,默认类型
3、@public:它修饰的实例变量可以在在任何位置进行访问
4、@package:常用于框架级别的实例变量中,使用private过于限制,public和protected过于开放
十六、简述MVC设置模式?
1、MVC即Model模型、View视图、Controller控制器
2、模型包含一些算法和数据;视图可以进行图形界面设计;控制器用来处理调度模型和视图去完成用户的需求。
3、MVC好处:a、低耦合性,更改视图层的代码不用重新编译模型和控制器代码
b、高重用性和适用性
c、较低的生命周期成本,MVC使得开发和维护用户接口的技术含量降低
d、团队分工合作开发,降低开发时间,提升效率
e、易于维护,视图层和一些业务逻辑层分离
十七、NSString*testObj = [[NSDataalloc]init];testObj在编译时和运行时分别是什么类型对象?
1、NSString*testObj是告诉编译器,testObj是一个指向OC对象的指针。这里限定NSString只不过是告诉编译器,将testObj当做一个字符串类型来检查
2、接着创建一个NSData对象,然后将这个对象的内存地址保存在testObj中,那么运行时,testObj指向的内存空间就是一个NSData对象。
十八、copy和retain的区别?
1、copy是创建一个新的对象,retain不是
2、copy是内容拷贝,深复制;retain是地址的拷贝
3、copy是建立一个引用计数为1的对象,然后释放旧对象;retain是释放旧对象,新对象引用计数加1,retain用于MRC
十九、assign和retain的区别?
1、assign是简单的赋值不更改引用计数,常用于基本数据类型OC的NSIntegerC语言的intfloat等
2、retain是释放就对象,新对象引用计数加1,用于MRC模式
二十、简要说明readonly和readwrite
1、readonly是只读,不可写入,只生成了get方法,声明该属性是防止外界任意修改
2、readwrite是默认属性,可读可写,需要实现它的set和get方法
二十一、weak和strong的区别?
1、这两个关键字用于ARC机制下,用来修饰变量,weak是弱引用,strong是强引用
2、strong相当于MRC机制下的retain,weak相当于MRC机制下的assign,但weak比assign多了一个功能,当对象消失后自动把指针变成nil,可以有效防止野指针
3、一般指针默认是强引用的
二十二、static关键字的作用?
1、static不能修饰类的实例变量和方法,可以修饰全局变量但只限在本文件中使用,可以修饰局部变量使得局部变量的生命周期延长
2、作用:a、static修饰的局部变量只会初始化一次,并且在程序退出时才会回收内存
b、static修饰的全部变量是一个内部变量,只能在本文件中使用,其他文件不能使用
c、static修饰的函数是一个内部函数,只能在本文件中使用,其他文件不能调用
d、在类中的static成员变量意味着它为该类的所有实例所共享,也就是说当某个类的实例修
改了该静态成员变量,其修改值为该类的其它所有实例所见;
e、在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类
的static成员变量。
二十三、线程和进程的联系和区别?
1、联系:进程和线程都是操作系统中程序运行的基本单元,进程是指系统中正在运行中的某个应用程序,且在一个受保护的内存空间内独立运行;而线程是进程的基本执行单元,一个进程所有的任务都要在线程上执行,简而言之:一个程序至少要有一个进程,一个进程至少要有一条线程
2、区别:a、进程间的内存空间相互独立,而多个线程是共享内存,可以提升运行效率
b、资源拥有:进程是系统资源分配和拥有的单位,同一个进程内的线程共享进程的资源,不能拥有系统的资源;
c、调度:线程是调度和分配的基本单位,进程是拥有系统资源的基本单位.
d、进程可以并发执行,进程中的线程也可以并发执行.
二十四、栈和堆的区别?
1、概念:栈用来存放程序临时创建的局部变量,特点先进后出;堆是存放程序运行过程中动态分配的内存段,常见为allocinit
2、管理方式:栈区内存由系统管理,堆区由程序员自己手动管理,如果没及时释放可能会导致野指针
3、分配方式:堆都是动态分配的;栈有动态和静态分配两种,静态分配由系统完成,动态分配是通过alloc函数分配的,但是区别于堆区的动态分配,因为栈区的动态分配也是系统负责管理
4、分配效率:栈区高于堆区,原因就是一个系统管理一个手动管理
5、碎片问题:堆区频繁的new、allocinit会造成内存空间的不连续,产生大量碎片使程序效率降低,栈区是先进后出,不会存在碎片问题
二十五、自动释放池什么时候被创建和销毁?有什么作用?底层如何实现?
1、作用:自动释放对象;所有autorelease的对象,在出了作用域之后,会被自动添加到最近创建的自动释放池中;自动释放池被销毁或者耗尽时,会向池中所有对象发送release消息,释放池中对象;自动释放池,在ARC & MRC程序中都有效
2、生命周期:运行循环检测到事件并启动后,就会创建自动释放池;一次完整的运行循环结束之前,会被销毁
3、底层实现:自动释放池以栈的形式实现:当你创建一个新的自动释放池时,它将被添加到栈顶。当一个对象收到autorelease消息时,该对象会被添加到这个处于栈顶的自动释放池中,当自动释放池被回收时,它们会从栈中被删除,并且会给池子里面所有的对象都会做一次release操作。
二十六、简要说明工厂方法?
1、概念:在基类中定义创建对象的一个接口,让子类决定实例化哪个类。工厂方法让一个类的实例化延迟到子类中进行,工厂方法要解决的问题是对象的创建时机,它提供了一种扩展的策略,很好地符合了开放封闭原则。
2、何时使用:一个类不知道它所必须创建的对象的类时,一个类希望有它的子类决定所创建的对象时
二十七、什么是动态类型和动态绑定?
1、动态类型:程序直到运行时才能确定对象的类型,简单说就是id类型,id指针可以指向任何对象,区别与静态类型,静态类型在编译时就能确定对象的类型。
2、动态绑定:基于动态类型将调用方法的确定也推迟到运行时,在某个实例对象被确定后,其类型便被确定了。该对象对应的属性和响应的消息也被完全确定,这就是动态绑定。
3、附加:动态加载,根据需求加载所需要的资源,比如Retina设备会加载@2x的图片!
///define
conest static ???
二十八、ViewController的loadView, viewDidLoad,
viewDidUnload分别是在什么时候调用的?有什么作用?
1、loadView在控制器的View为nil的时候调用,如果重写了该方法,sb中就是有视图也不会加载
作用:负责创建控制器的view
2、viewDidLoad在视图view加载完毕时调用,无论怎样创建的view
作用:一般可以在这里做一些初始化操作,如添加子视图等
3、viewDidUnload在应用程序内存过多,收到内存警告释放view时调用
作用:主要是释放界面元素的相关资源,将相关的实例赋值为nil
4、三者的顺序:第一次访问VC的view时,view为nil,然后调用loadView方法创建view,view创建完毕调用viewDidLoad进行界面初始化,当内存警告时,系统可能会释放VC的view,并将view设置为nil,并且调用viewDidUnload方法,当再次访问VC的view时,view之前已经设置为nil,所以重新调loadView方法……
二十九、nil、NULL、Nil、null的区别?
1、NULL是C语言中的空指针
2、nil是OC中的空对象,地址指向空
3、Nil是空的类对象
4、null是空字符串,一般是服务器返回的
5、NSNull用于解决向NSArray和NSDictionary等集合添加空值的问题
三十、图层CALayer和UIView的区别?
1、UIView是iOS系统中界面元素的基础,所有的界面元素都是继承自它。它本身完全是由CoreAnimation来实现的。真正的绘图部分,是由CALayer类来管理。UIView本身更像是一个CALayer的管理器。
2、UIView继承结构为:UIResponder---------NSObject,直接父类为UIResponder,直接父类是用来响应用户事件的,所以UIView可以响应用户事件
CALayer的继承结构为:NSObject,直接父类没有UIResponder,所以CALayer不能响应任何用户事件
3、UIView属于UIKit框架,CALayer属于QuartzCore框架
三十一、简要说明GCD?
1、全称:GrandCentralDispatch,纯C语言,提供了非常强大的函数
2、优势:a、是苹果公司为多核的并发运算提出的解决方法
b、会自动利用更多得CPU内核(双核、四核)
c、自动管理线程的生命周期(创建线程、调度任务、销毁线程)
d、程序员只需告诉GCD要执行什么任务,不需要编写线程管理的代码
3、核心概念:将任务添加到队列,并指定执行任务的函数,任务用block封装,执行函数分同步和异步,队列分串行、并发和主队列
三十二、什么是TCP连接的三次握手?
1、第一次握手:客户端发送syn(同步序列编号)包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
2、第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
3、第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
4、如果要断开连接,就需要任意一方主动发起请求,可以理解为第四次握手!
三十三、利用Socket建立网络连接的步骤(等同于Socket间如何通信)?
1、创建套接字,建立地址和套接字之间的联系
2、服务器监听客户端的请求,之后建立客户端和服务器的连接
3、发送和接受数据
4、关闭套接字
三十四、什么是指针的释放?
1、其实是释放指针指向的内存空间,指针是一个变量,程序结束时才会销毁,并且只有堆上的内存才需要我们手动管理
2、将该指针初始化为NULL
三十五、指针和地址的区别?
1、指针意味着已经有一个指针变量存在,他的值是一个地址,指针变量本身也存放在一个长度为8个字节的地址当中,而地址概念本身并不代表有任何变量存在.
2、指针的值,如果没有限制,通常是可以变化的,也可以指向另外一个地址.地址表示内存空间的一个位置点,他是用来赋给指针的,地址本身是没有大小概念,指针指向变量的大小,取决于地址后面存放的变量类型.
三十六、Internet采用哪种网络协议?该协议的主要层次结构?
1、TCP/IP
2、应用层/传输层/网络互联层/网络接口层
三十七、局部变量能否和全局变量重名?
1、能,局部会屏蔽全局。要用全局变量,需要使用"::"
局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而
不会用到全局变量。对于有些编译器而言,在同一个函数内可以定义多个同名的局部变
量,比如在两个循环体内都定义一个同名的局部变量,而那个局部变量的作用域就在那
个循环体内
三十八、语句for(;1;)有什么问题?它是什么意思?
1、死循环,和while(1)一样,最简单的死循环
三十九、do……while和while……do有什么区别?
1、前一个循环一遍再判断,后一个判断以后再循环、
四十、针对APP显示webView时的内存问题应该如果优化?
1、后端程序员做优化
2、专门针对手机做页面,需要精简内容
3、优化框架,有些后端的框架非常消耗内存,需要精简框架
4、优化网络统计js
5、针对手机提供定制的图片
四十一、谈谈运行时Runtime机制,适用范围是什么,并写出相关的头文件和方法名?
1、runtime是一套C语言比较底层的API,属于一个C语言库,平时编写的OC代码在程序运行过程中都转成了runtime的C语言代码
2、适用范围:A、动态获取类的属性,常见于字典转模型的框架
B、利用关联对象为分类动态添加属性
C、利用交换方法拦截系统或框架的方法
D、动态给某个类添加属性和方法
3、相关应用:A、NSCoding(归档和解档,利用runtime遍历模型对象的所有属性)
B、字典转模型(利用runtime遍历模型对象的所有属性,根号属性名从字典中取出对应的值,设置到模型属性上)
C、KVO(利用runtime动态产生一个类)
D、用于封装框架
4、头文件:#import #import
5、方法名:获取类的属性:class_copyPropertyList()
关联对象:objc_getAssociatedObject()和objc_setAssociatedObject()
交换方法:class_getInstanceMethod()
四十二、简述KVO的底层实现原理?
1、KVO(Key Value
Observing)是观察者模式在Foundation中的实现,是基于runtime实现的
2、原理:以Person *p = [[Person alloc]init]为例;
a、当给对象p添加了观察者时,会动态创建这个Person类的子类(NSKVONotifying_Person)
b、对被观察对象p的属性重写其set方法
c、在重写的set方法中调用willChangeValueForKey和didChangeValueForKey方法通知观察者进行观察
d、当属性没有观察者时就会删除重写的set方法,当没有观察者观察任何一个属性时,就会动态删除这个类的子类
四十三、写一个标准的宏定义求三个数最小值和最大值?
1、最小值:#define Min(a,b,c)
(a
2、最大值:#define Max(a,b,c)
(a>b?(a>c?a:c):(b>c?b:c))
四十四、KVC的底层实现:setValuesForKeysWithDictionary:
1、逐个取出字典当中的key,判断调用对象有没有set方法,如果有,直接赋值;
2、若没有,去对象中查找,有没有带下划线的成员属性_key,如果有就直接赋值;
3、若没有,去对象中查找,有没有不带下划线的成员属性key,如果有就直接赋值;
4、若没有,表示没有找到对象里面的属性,就会直接报错.
所以,我们在利用KVC的时候,要保证对象里面的属性和Key要一一对应;
四十五、这个写法会出什么问题:@property (atomic,copy) NSMutableArray *array
1、添加,删除,修改数组内的元素的时候,程序会因为找不到对应的方法而崩溃.因为copy就是复制一个不可变NSArray的对象
2、atomic应写成nonatominc,因为他会影响性能,该属性使用了同步锁,会在创建时生成一些额外的代码用于帮助编写多线程程序,这会带来性能问题,通过声明nonatomic可以节省这些虽然很小但是不必要额外开销,因此,开发iOS程序时一般都会使用nonatomic属性
四十六、@property的本质是什么?
1、@property = ivar + getter + setter;
“属性”(property)有两大概念:ivar(实例变量/成员变量)、存取方法(access method=getter + setter)
四十七、交换两个数值的方法?
例如:inta = 6b =8
1、中间变量inttemp;temp=a;a =b;b =temp;
2、加减法a =a +b;b =a-b;a=a-b;
3、按位异或a=a^b;b = ab;a=ab;
四十八、MRC和ARC混合开发,项目开发中遇到MRC开发的第三方库怎么办?
例如:ASI
1、首先尝试使用Xcode的转换工具(但失败率比较高)Edit --> Convert --> To Objective-C ARC
2、在编译选项中,为MRC的程序添加-fno-objc-arc标记,表明在编译时,该文件使用MRC编译,如果要在MRC项目中添加ARC的文件,可以使用-fobjc-arc标记
3、将MRC的第三方库直接编译成静态库使用,需要注意的是:在编译静态库时,不能添加动态库引用,在项目中,如果使用的静态库中包含分类,则需要在Other Link Flag中添加-ObjC选项
四十九、常用的设计模式?使用场景及优点?
1、代理模式:传入的对象代替当前类完成某些功能
使用场景:当A对象无法处理某些行为时,可以找B对象帮忙处理、此时B就充当A的代理
优点:解耦合
2、观察者模式:观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象
使用场合:KVO(Key-Value Observing),当指定的被观察者对象属性发生变化时,KVO通知响应的观察者执行某些操作
通知:定义回调方法,即接收到通知时应该执行什么功能;之后在通知中心注册通知,告诉通知中心对什么"感兴趣";当通知中心发送通知
(程序的任何位置)时执行回调方法
在没有返回值、视图层次嵌套很深时使用,因为用代理逐层传递很繁琐
优点:解耦合
3、MVC模式:(Model,View,Controller)古老的设计模式
使用场景:模型提供数据,控制器掌管逻辑,视图展示界面
优点:层次清晰、职责分明,易于维护
4、单例模式:保证整个程序运行只有一个实例,且易于外界共享、访问
使用场景:如多线程的线程池、操作系统的文件系统,多个程序访问同一个配置文件等,工具类常用
优点:某些对象在程序整个生命周期中只需有一个实例存在,防止多处被实例化,能保证数据的准确性,也节约内存资源
5、工厂方法:基类中定义创建对象的一个接口,让子类决定实例化哪个类,让一个类的实例化延迟到子类中进行
使用场景:a、作为创建类的模式,任何需要创建复杂对象的时候都可使使用
b、是依赖抽象架构的,把实例化产品的任务交给实现类完成,扩展性好,当系统需要较好扩展性时可以使用
优点:面向抽象编程,易于替换、扩展性好
6、策略模式:实现某一个功能会有多种算法和策略,可以将这个算法写到一个类中,然后提供一些方法,一个方法对应一个具体的算法
也可以将算法封装在一个统一的方法中
使用场景:定义算法族,把每个算法封装起来并且使之可相互替换
优点:使算法的变化独立于使用算法的对象
7、适配器模式:是一种结构性设计模式
作用:复用一些现存的类,但是接口又与复用环境不太一致的时候可以使用
五十、Swift和OC的区别?
1、Swift没有地址和指针的概念
2、Swift对数据类型要求极为严谨
3、泛型,泛型代码能写出更加灵活清晰、可重复使用的函数
五十一、如何实现OC和Javascript交互?
1、ios应用一般通过UIWebView实现OC与Javascript的交互,具体如下
2、OC调用JS:在UIWebView的代理方法webViewDidFinishLoad中利用WebView唯一与JS交互的方法
- (NSString*)stringByEvaluatingJavaScriptFromString:(NSString *)script;
3、JS调用OC:利用html的重定向技术,使用下面方法截取重定向
-(BOOL)webView:(UIWebView *)webView
shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType
五十二、HTTP和Socket通信之间的区别?
1、A >HTTP(超文本传输协议)是建立在TCP协议上的应用,简单、规模小、通信速度快,用于定义网络数据传输的格式
B >最显著特点是客户端每次请求都需要服务器的响应,响应完成会主动释放连接,节约传输时间
C >完整的HTTP通信必须包含请求(请求头、请求行、请求体)和响应(状态行、响应头、实体内容)
2、A >Socket是纯C语言的,客户端与服务器使用socket套接字进行连接,它是一种用于传输网络数据的工具
B >Scoket是对TCP/IP协议的封装和应用,简单说,TCP/IP协议是传输层协议,主要解决数据如何在网络上传输,HTTP是应用层协议,主要负责解决如何包装数据
C >Socket连接过程:建立连接、客户端请求数据、服务器回应数据、结束连接
D >Socket有长短连接和心跳包的概念(短连接是数据请求结束立刻断开;长连接是一旦建立连接始终保持;心跳包是检测长连接的手段客户端和服务器都可以发送)
五十三、TCP与UDP的区别?
1、概念:TCP(传输控制协议)是基于连接的协议,正式收发数据前必须建立可靠的连接
UDF(用户数据报协议)是基于非连接的协议,只管发送,不与对方建立连接
2、数据传输大小:UDP每个数据报大小在64k之内
TCP传输数据大小不受限,所以对系统资源的要求要高于UDP
3、可靠性:UDP无需建立连接故而不可靠,易丢包
TCP需要三次握手才能建立连接,可靠
4、传输效率:UDP > TCP,因为TCP多了建立连接的步骤
五十四、SAX解析与DOM解析的区别?
1、SAX:是只读的方式,从上向下的方式解析;是苹果提供的解析方式;速度快;适合对大型的XML的解析;用5个代理方法解析
2、DOM:是在MAC使用的解析方式,可读可写,内存消耗极大,解析速度慢,ios默认不支持
五十五、多线程有什么优点和缺点?
1、优点:使应用程序响应速度更快,用户界面在进行其他工作时仍始终保持活动状态,提高程序执行效率
优化任务的执行,适当提高资源利用率
2、缺点:线程占用内存空间,管理内存需要额外的cpu开销,开启大量线程降低程序的性能
增加程序复杂程度,如线程间通信,多线程的资源共享
五十六、GCD和NSOperation的区别?
1、相对于GCD:
A> NSOperation有更多的函数可用
B> NSOperationQueue中可以跨对列设置操作的依赖关系
C>可使用KVO监听操作是否执行结束或取消
D>可以设置最大操作并发数
2、相当于NSOperation:
A> GCD是C语言的API,ios4.0推出在性能上做了优化,而且对NSOperation底层全部重写
B> GCD充分利用多核处理器并发处理任务,效率高
C> GCD不用程序员管理线程开闭,完全由系统管理,比较轻量级
D>高级功能:调度组、延时操作after、和一次性(单例)
五十七、ios多线程技术(实现方案)及特点?
1、pthread是一套通用的多线程API,适用于多个系统,跨平台可移植使用难度大,底层是C语言,线程生命周期由程序员管理,几乎不用
2、NSThread更加面向对象,简单易用,可直接操作线程对象,OC语言,线程生命周期也由程序员管理,偶尔使用
3、GCD是替代NSThread的线程技术,底层也是C语言,线程的生命周期由系统管理,经常使用
4、NSOperation基于GCD,比GCD多了些实用的功能,更加面向对象,OC编写,线程生命周期也是系统管理,经常使用
五十八、简要介绍运行循环Runloop?
1、概念:一个线程一次只能执行一个任务,执行完毕后线程就会退出,而Runloop就是一个让线程随时处理事件但不退出的一套机制
2、特点:每个线程都有一个运行循环,主线程默认是开启的,子线程需要手动开启;苹果不允许直接创建Runloop只能通过获取函数获取
3、作用:A>使程序一直运行并接收用户的输入,保证主线程不退出
B>决定程序在何时处理哪些事件
C>调用解耦(Message Queue)
D>节省CPU时间(当程序启动后,什么都没有执行的话,就不用让CPU来消耗资源来执行,直接进入睡眠状态)
五十九、描述响应者链条?
1、概念:多个响应者对象连接起来的链条
响应者对象:继承自UIResponder的对象
2、作用:可以让触摸事件发生的时候多个响应者同时响应1该事件
3、事件传递过程:UIApplication--->UIWindow--->由上向下由父控件到子控件找到最合适的view处理事件
响应者链条的事件传递过程:A>如果view是控制器的view就传递给控制器,如果不是就传递给它的父视图
B>在视图层次结构的最顶级视图如果也不能处理接收的事件,则将事件传递给window进行处理
C>window如果也不能处理就将事件传递给UIApplication处理
D>如果UIApplication也不能处理则将事件直接丢弃
4、判断上一个响应者的标准:先判断当前view是不是控制器的view,是的话控制器就是上一个响应者
如果当前这个view不是控制器的view,那么父控件就是上一个响应者
六十、new和allocinit的区别?
1、概括的说:二者功能基本一致,分配内存空间并完成初始化
2、差别在于:采用new的方式只能采用默认的init方法完成初始化,而采用的方式可以使用其他的定制的初始化方法
六十一、创建控制器view的过程(优先级)?
1、先看有没有重写系统的loadView方法,有的话就根据loadView的代码创建view
2、没有重写loadView的话就寻找有没有指定的sb,有就通过sb的描述创建view
3、没有的话就寻找有没有指定nibName,如果有,就根据nibName对应的xib去创建(如:LGViewController.xib)
4、没有的话会寻找有没有跟控制器同名,不带Controller的xib,有就创建
5、如果没有就去找跟控制器同名带Controller的xib,有就创建
6、没有就直接创建几乎透明的view
六十二、应用的状态和生命周期?
1、状态:
A、Notrunning未运行:程序未启动
B、Inactive程序正在前台运行不过没有接收到事件
C、Active程序在前台运行而且在接收事件
D、Backgroound程序在后台运行执行代码
E、Suspended程序在后台运行但不执行代码
注意:状态发生转换时会调用代理对象对应的方法相应App状态的改变,上面就是常用的代理方法
2、生命周期:
A、application:willFinishLaunchingWithOptions:
-将要完成启动(此时会告诉代理进程启动但还没进入状态保存)
B、application:didFinishLaunchingWithOptions:
-启动完成(告诉代理启动完成准备开始运行,该方法允许显示app给用户前执行最后的初始化操作)
C、applicationWillResignActive: - app将要从前台切换到后台时需要执行的操作(如来电话了,此时程序不接收消息和事件)
D、applicationDidBecomeActive: - app从后台再切回至前台时调用
E、applicationDidEnterBackground: - app已经进入后台后需要执行的操作
F、applicationWillEnterForeground: - app将要从后台切换到前台需要执行的操作,但app还不是active状态
G、applicationWillTerminate: - app将要退出时需要执行的操作(通常可以做一些保存数据清理缓存的工作)
注意:APP在不同状态下3、4、5、6的执行顺序并不固定!
六十三、开发中哪些地方用到过多线程?
1、预先加载图像,用到dispatch_group_enter,利用通知统一监听
2、SQLite的异步操作,使用串行队列顺序调度任务,保证数据的完整性
3、图像压缩,异步压缩,完成之后回调
六十四、load和initialize的异同?
1、相同点:方法只会被调用一次(开发者不主动调用的前提下)
2、不同点:A:load是只要类所在文件被引用(import)的时候就会被调用
initialize是在当前类第一次被执行到的时候会被调用
B:若自身未定义initialize会沿用父类的方法,load不会沿用
六十五、block属性为什么用copy?使用时应注意什么?使用场景?原理是什么?有什么优点?
1、A:使用copy可以将block从栈区复制到堆区,因为栈区由系统管理,存在栈区随时可能被回收,或是出作用域即被回收!
B:block用于保存代码,调用时才执行,但有时调用block时,block中用到的其他对象可能已经被释放,使用copy可以保证调用block是外界对象
依然存在
2、注意:循环引用,block中用到self可以用__weak修饰防止循环引用
3、应用场景:动画、数组字典排序遍历、网络访问时错误回调、GCD
4、原理:本质是指向结构体的指针,编译器会将block内部代码生成对应函数
5、优点:代码思路更加清晰,易于阅读和维护
六十六、开发中最容易引起循环引用的场景?
1、声明代理属性要使用weak
2、block代码块中的self要换成weakSelf( __weaktypeof(self)weakSelf = self)
3、NSTimer定时器self.timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self
selector:@selector(nextPage) userInfo:nil repeats:YES];//类持有timer,timer又持有self(即:target : self),所以每次需要将timer设置为无效invalidate并设置为nil
六十七、NSValue和NSNumber的区别?
1、NSNumber继承自NSValue,是NSValue的子类
2、NSNumber可以将基本数据类型包装成对象放到数组或字典中
3、NSValue可以包装任意类型,可以是系统框架提供的数据结构也可以是自定义的结构体
六十八、ARC下,不显式的指定属性的关键字时,默认关键字是什么?
1、对于基本数据类型默认关键字为:atomic、readwrite、assign
2、对于普通的OC对象默认关键字为:atominc、readwrite、strong
六十九、用@property声明的NSString属性通常使用copy修饰,为什么?如果换成strong会有什么影响?
1、因为父类指针可以指向子类对象,使用copy可以让对象的属性不受外界影响,使用copy后无论给属性传入是一个可变对象还是不可对象,属性本身持有的就是一个不可变的副本.
2、如果使用是strong,那么这个属性就有可能指向一个可变对象,如果这个可变对象在外部被修改了,那么会影响该属性.
注意:
[immutableObject copy] //浅复制
[immutableObject mutableCopy] //深复制
[mutableObject copy] //深复制
[mutableObject mutableCopy] //深复制
七十、如何让自己的类用copy修饰符?如何重写带copy关键字的setter?
1、如果想让自己所写的对象具有拷贝功能,则需实现NSCopying协议。如果自定义的对象分为可变版本与不可变版本,那么就要同时实现NSCopyiog与NSMutableCopying协议。
2、需声明该类遵从NSCopying协议;实现NSCopying协议。该协议只有一个方法:(id)copyWithZone: (NSZone*)zone;
七十一、一个objc对象的isa指针指向什么?
1、实例对象的isa指针指向它的类,类的isa指针指向该类的metaclass(元类),而元类定义了类方法的列表
七十二、OC中类方法和对象(实例)方法有什么本质区别和联系?
1、类方法:
A:类方法是属于类对象的
B;类方法只能通过类对象调用
C:类方法中的self是类对象
D:类方法可以调用其他的类方法
E:类方法不能直接访问成员变量
F:类方法中不能直接调用对象方法
2、对象方法:
A:对象方法属于实例对象
B;对象方法只能通过实例对象调用
C:对象方法中的self是实例对象
D:对象方法中可以访问成员变量
E:对象方法中可直接调用其他对象方法
F:对象方法中也可以调用类方法(通过类)
七十三、OC中有哪几种遍历的方法?哪个效率比较高?
1、普通for循环
2、for循环增强for-in
3、block代码块enumrateObjectsUsingBlock
4、枚举器:NSEnumerator
效率:for -in效率最高2s左右,其余都在2.6~3.0s之间
七十四、runtime如何实现将weak修饰的对象自动设置为nil?
1、runtime对注册的类,会进行布局,对于weak对象会放入一个hash表中。用weak指向的对象内存地址作为key,当此对象的引用计数为0的时候会dealloc,假如weak指向的对象内存地址是a,那么就会以a为键,在这个weak表中搜索,找到所有以a为键的weak对象,并设置为nil
七十五、runloop(运行循环)和线程的联系?
1、简要的说:runloop就是为线程而生的,没有线程runloop就没有存在的必要
2、每个线程都有与之对应的runloop对象,主线程的运行循环默认是开启的,子线程需手动开启
3、在任何一个Cocoa程序的线程中,都可以通过以下代码来获取到当前线程的run loop
NSRunLoop *runloop = [NSRunLoopcurrentRunLoop];
七十六、ARC通过什么帮助程序员管理内存?
1、编译时,通过代码的上下文在适当位置插入retain和release
七十七、苹果的自动释放池(autoreleasepool)是怎么实现的?
1、autoreleasepool以一个队列数组的形式实现,主要通过下列三个函数完成.
A、objc_autoreleasepoolPush
B、objc_autoreleasepoolPop
C、objc_aurorelease
通过函数名可知:push进释放池池,pop出释放池,最后销毁对象时执行release操作
七十八、dispatch_barrier_async的作用是什么?
1、通俗来讲:在并发队列中,为了保持某些任务的顺序,需要等待一些任务完成后才能继续进行,使用barrier来等待之前任务完成,避免数据竞争等问题
2、专业来讲:使用dispatch_barrier_async添加的block会在之前添加的block全部运行结束之后,才在同一个线程顺序执行,从而保证对非线程安全的对象进行正确的操作!
3、使用注意:必须使用自定义并发队列,否则执行效果和全局队列一致,无法阻塞线程
七十九、addObserver:forKeyPath:options:context:各个参数的作用分别是什么,observer中需要实现哪个方法才能获得KVO回调?
1、添加观察者方法的参数:观察者、观察的属性、观察的选项、上下文
2、回调方法的参数:观察的属性、观察的对象、change属性变化的字典、上下文(与添加时一致)
(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
change:(NSDictionary *)change context:(void *)context;
八十、IB中User Defined Runtime Attributes如何使用?
1、它能够通过KVC的方式配置一些你在interface
builder中不能配置的属性。当你希望在IB中作尽可能多得事情,这个特性能够帮助你编写更加轻量级的viewcontroller,只要响应的attribute
type代表相同的数据类型,那么他们就可以相互替换使用
八十一、lldb常用调试指令?
1、b:查看当前所有断点c:继续r:重新运行n:下一步p:打印s:单步po:打印对象
八十二、如何调试BAD_ACCESS错误?
1、重写object的respondsToSelector方法,现实出现EXEC_BAD_ACCESS前访问的最后一个object
2、通过开启EditScheme中的Zombie
3、设置全局断点定位
4、Xcode 7已经集成了BAD_ACCESS捕获功能:Address
Sanitizer在配置中勾选✅Enable Address Sanitizer
八十三、风格纠错题!!!
八十四、initWithCoder、awakeFromNib、initWithNibName、initWithFrame?
1、initWithCoder:当一个类在IB中创建,但在Xcode中被实例化的时候被调用的,也可以说当从nib文件中加载对象的时候调用。如:通过IB拖一个控制器,然后在Xcode中通过initWithNibName来实例化这个控制器的时候,这个控制器的initWithCoder就会被调用
2、awakeFromNib:当nib文件被加载的时候,会向nib文件中的每个对象发送一个awakeFromNib消息,每个对象都可以定义自己的awakeFromNib函数来相应这个消息,总之:通过nib文件创建view对象时会调用awakeFromNib
3、initWithNibName:当一个控制器或某个控件在IB中创建,在Xcode中需要调用这个方法来实例化它们,此时调用该方法
4、initWithFrame:当我们使用代码创建视图内容,不使用Nib文件时,需要调用initWithFrame去初始化对象
补充:1、xib和nib都是Interface Builder的图形界面设计文档,xib是一个XML格式的纯文本文件,nib是一个二进制文件,目前Xcode默认使用xib格式的文档
补充:2、IB,即InterfaceBiulder,是MacOSX系统下用与设计和测试用户界面的应用程序
八十五、Notification是同步还是异步?和代理相比有什么效率上有什么区别?
1、通知的注册和发送都通过通知中心完成的,通知中心的消息转发是同步执行的
2、通知可以一对多、多对多,代理是一对一的关系
效率上:如果不需要返回值,视图层次嵌套比较深的时候建议使用通知
代理常用在视图和控制器之间,当视图视图不能实现某种功能是可以让控制器做代理,辅助实现!
八十六、ViewController中的didReceiveMemoryWaring是在什么时候调用?默认的操作是什么?
1、当程序接收到内存警告时会调用该方法
2、会将控制器的view释放掉,并调用viewDidUnLoad方法
八十七、UIImage的imageNamed和imageWithContentOfFile有什么区别?
1、最明显区别:一个传图片的名称,一个传图片文件的路径
2、imageNamed:使用该方法加载图片会把图片缓存下来,当图片频繁使用时,直接从内存中取,例如:TableView里的TableViewCell加载同一个图像时
3、imageContentOfFile:仅加载图片,图像数据不会缓存,对于较大图片或图片数量较少时,可以使用
八十八、对于NSString*obj=[[NSDataalloc] init];,编译时和运行时obj分别是什么类型?
1、编译时是NSString类型
2、运行时是NSData类型
八十九、常见的OC数据类型有哪些?和C的基本数据类型有什么区别?
1、OC常用数据类型:NSString、NSSArray、NSDictionary、NSData、NSNumber等
2、区别:OC对象需要手动管理内存,C语言的基本数据类型不需要管理内存
九十、简要说明消息推送?
1、通俗的讲:应用程序在没有运行的状态下也可以接收到消息
2、本地推送:程序内部弹出,即本应用负责执行推送的操作
3、远程推送:由服务器的程序发送推送通知APNS,再由APNS把消息推送给设备上的程序
九十一、TableView为什么使用的重用机制?简述过程?
1、原因:对于一个TableView可能需要显示大量的cell,如果每个cell都需要单独创建会消耗很大的内存,为了避免这种情况,所以引入了重用机制
2、过程:在创建cell的时候绑定一个可重用的标示符,当cell离开界面时会添加重用队列中,要显示新的cell的时候直接去重用队列中取,不用再单独创建,提高效率,节约内存消耗
九十二、为什么使用第三方框架?
1、第三方框架把复杂的底层操作,封装成了友好的类和方法,并且加入了异常处理
2、优点:大大提升开发效率,节约开发时间
九十三、简述NSURLSession?
1、ios7之后推出,为了方便程序员使用,苹果提供了一个全局session,用于替代NSURLConection
2、支持后台运行的网络任务,网络任务可以实现暂停、停止、重启
3、使用URLSession后,NSURLRequest通常只用于指定HTTP请求方法,而其他的额外信息都可以通过NSURLSessionConfiguration设置
4、默认所有任务都是挂起的状态,需要手动resume
5、支持三种类型任务:加载数据、下载和上传
九十四、ios应用中地图是如何实现定位的?
1、ios中通过Core Location框架进行定位操作,和地图开发框架MapKit完全独立,二者可配合使用
2、CoreLocation中包含定位、地理编码等功能
九十五、obj-c有多重继承吗?没有的话有什么代替?
1、Object-c只支持单继承,如果要实现多继承可以通过类别和协议的方式实现
九十六、简单介绍下真机上调试时开发证书的申请流程?
1、先在本地生成获取证书的文件
2、请求证书,填写必要的信息,保存路径和生成文件的名称
3、到苹果官网的开发者界面,添加证书,然后把申请完成的CSR文件下载下来
4、申请AppID,填写信息
5、绑定iphone设备,填写设备信息
6、配置文件信息
7、绑定之前的AppID、调试证书、和设备信息,把申请的配置文件下载到本地
8、修改Xcode信息BundleIdentifier
九十七、真机调试的主要步骤?
1、登录开发者主页
2、生成cer证书:cer是一个跟电脑相关的证书文件,让电脑具备真机调试的功能
3、添加AppID:调试哪些app
4、注册真机设备:那台设备需要做真机测试
5、生成MobileProvision文件
6、导入cer、MobileProvision文件
九十八、什么是XMPP?工作原理是什么?
1、XMPP是基于XML通讯的协议,基于TCP发送XML数据,一般用于即时通讯(QQ/微信)
2、原理:A、节点连接到服务器
B、服务器利用本地目录系统中的证书对其认证
C、节点指定目标地址,让服务器告知目标状态
D、服务器查找、连接并进行相互认证
E、节点之间进行交互
九十九、http中的POST请求和GET请求的区别和联系?如何选择?
1、GET是从服务器获取数据,POST是向服务器发送数据
2、GET请求能够被缓存,POST请求不能被缓存
3、GET请求对数据大小有限制,POST没有大小限制
4、使用GET请求,参数会显示出来,而POST则不会,POST更安全一些
5、GET的效率要高于POST,因为POST多了一步解析二进制参数的过程
如何选择:如果数据是中文数据而且是非敏感数据应该使用GET,如果数据中包含用户的隐私信息(账户、密码等)尽量使用POST
一零零、iOS的远程消息推送(Push)是怎么实现的?
1、[Client App]注册消息推送(通过设备唯一标示UDID和应用的唯一标示BundleID);
2、[Client App]跟[APNS Service]要deviceToken, Client App接收deviceToken;
3、[Client App]将deviceToken发送给[Provider]Push服务端程序;
4、当Push服务端程序满足发送消息条件时,[Provider]将deviceToken和消息体等打包向[APNS Service]发送消息;
5、[APNS Service]会利用deviceToken找到对应的[Client App]并将消息体传达.
一零一、逻辑运算和位运算的区别?
1、位运算针对的是二进制数据,逻辑运算用于判断条件
一零二、冒泡排序、选择排序的原理及核心代码?
1、冒泡排序原理:从数组的第一个位置开始两两比较array[index]和array[index+1],如果前者大于后者就交换位
置,直到数组结束
核心代码:for(int i=0;i
for (intj=0; j
if (a[j]>a[j+1]) {
int temp;
temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
2、选择排序原理:选择一个值array[0]作为标杆,然后循环找到除这个值外最小的值(查找小于标杆的最小值),交换这两个值,这时最小值就被放到了array[0]上,然后再将array[1]作为标杆,从剩下未排序的值中找到最小值,并交换这两个值
核心代码:for (int i=0; i
for (intj=i+1; j
if(arr[i]>arr[j]){
int temp;
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
一零三、iphone中常用于实现数据存储的方式,并将每种方式用最简单的代码实现?
1、NSKeyedArchiver采用归档的形式存储(常用于NSString,
NSDictionary, NSArray, NSData, NSNumber等类型),需遵守NSCoding协议
归档对象时:会调用encodeWithCoder,一般在这个方法里面指定如何归档对象中的每个实例变量.可以使用:encodeObject:forkey:方法归档实例变量
解档对象时:会调用initWithCoder,一般在这个方法里面指定如何解码文件中的数据为对象的实例变量,可以使用decodeObject:forkey方法解码实例变量
2、NSUserDefaults偏好设置存储,常见保存用户名和密码,一般需要调用synchronize方法强制写入
存入:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:@"JN521" forKey:@"username"];
[defaults setFloat:18.0f forKey:@"text_size"];
[defaults setBool:YES forKey:@"auto_login"];
读取:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *username = [defaults stringForKey:@"username"];
float textSize = [defaults floatForKey:@"text_size"];
BOOL autoLogin = [defaults boolForKey:@"auto_login"];
3、write写入的形式永久保存到磁盘
NSArray *docPath =[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES) objectAtIndex:0];//获取文件即将保存的路径
NSString*FileName=[documentDirectory stringByAppendingPathComponent:fileName]//生成该路径下得文件
[datawriteToFile:FileName atomically:YES];//写入
4、属性列表(plist存储)属性列表是一种XML格式的文件,拓展名为plist如果对象是NSString, NSDictionary, NSArray, NSData,
NSNumber等类型,就可以使用:writeToFile:atomiclly:方法直接将对象写到属性列表文件中.
存入:
//将数据封装成字典
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:@"15013141314" forKey:@"phone"];
[dict setObject:@"27" forKey:@"age"];
//将字典持久化到Documents/stu.plist文件中
[dict writeToFile:path atomically:YES];
读取:
//读取Documents/stu.plist的内容,实例化NSDictionary
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
NSLog(@"phone:%@", [dict objectForKey:@"phone"]);
NSLog(@"age:%@", [dict objectForKey:@"age"]);
5、数据库存储SQLite
概念:SQLite是一个进程内的库,本质上就是一个文件,是一个SQL数据库引擎
特点:自给自足不需要外部依赖、无需单独服务器、零配置、轻量级、占用资源少、处理速度快
使用步骤:添加动态库(libsqlite3.dylib)、导头文件sqlite3、建立数据库、创建数据表、利用SQL命令增删改查
优点:将网络数据存到本地不用每次都加载,减少网络流量开销,可对本地数据进行系统性查询
SQLite命令:INSERT增/UPDATE改/DELETE删/SELECT查
一零四、线程间如何通信?
1、线程间通信:在一个进程中往往不止一条线程,那么多个线程之间就需要协调工作,此时就需要线程间通信
2、体现:线程间传递数据、一个线程执行完任务转到另一个线程继续执行
3、常用方法:
主线程执行操作,刷新UI:- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
指定线程执行:- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;
后台线程执行耗时的下载操作:[self
performSelectorInBackground:@selector(downloadImage) withObject:nil];
一零四、线程间如何通信?
1、线程间通信:在一个进程中往往不止一条线程,那么多个线程之间就需要协调工作,此时就需要线程间通信
2、体现:线程间传递数据、一个线程执行完任务转到另一个线程继续执行
3、常用方法:
主线程执行操作,刷新UI:- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
指定线程执行:- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;
后台线程执行耗时的下载操作:[self
performSelectorInBackground:@selector(downloadImage) withObject:nil];
一零五、谈谈多线程安全的几种解决办法?
1、主线程负责刷新UI
2、防止资源抢夺的情况,要进行加锁保护
3、如果异步操作要保证线程安全,尽量使用GCD,因为GCD有些默认的接口就是安全的
一零六、GCD底层是如何实现的?
1、iOS和OSX的核心是XNU内核,GCD是基于XNU内核实现的
2、GCD的API全部在libdispatch库中
3、GCD的底层实现主要有DispatchQueue和DispatchSource,前者管理操作(block),后者处理事件
一零七、block在ARC中和MRC中的用法有什么区别,需要注意什么?
1、MRC中block默认在栈区,ARC中的block会被复制到堆区
2、对于没有引用外部变量的Block,无论在ARC还是MRC下,类型都是NSGlobalBlock,这种类型的block可以理解成一种全局的block,不需要考虑作用域问题。同时,对他进行Copy或者Retain操作也是无效的
3、需要注意:循环引用
一零八、Foundation对象和CoreFoundation对象有什么区别?
1、前者针对OC对象,后者针对的是C语言对象(结构体)
2、ARC机制下,只管理OC的对象,不能管理CF对象,需要手动(CFRetain/CFRealease)管理,所以需要使用到__bridge,__bridge_retained和__bridge_transfer三个转换关键字
3、__bridge_retained后面跟CF对象,会转让所有权,将OC对象转成CF对象,后续需要调用CFRealease或相关方法释放对象;
__bridge_transfer后面跟OC对象,也会转让所有权,将CF对象转成OC对象,转换后自动调用CFRealease
一零九、简述客户端的缓存机制?
1、缓存可分为:内存数据缓存、数据库缓存、文件缓存
2、步骤:A:每次想获取数据时,先检查内存是否有缓存
B:再检查本地是否有缓存(数据库、沙盒)
C:最终发送网络请求去网络加载
D:将服务器返回的网络数据进行缓存以便再次使用
一一零、怎么解决缓存池满的问题(cell)?
1、一般情况下,ios中不存在缓存池满的情况
2、因为通常我们ios中开发,对象都是在需要的时候才会创建,有种常用的说话叫做懒加载,还有在UITableView中一般只会创建刚开始出现在屏幕中的cell,之后都是从缓存池里取,不会在创建新对象。缓存池里最多也就一两个对象,缓存池满的这种情况一般在开发java中比较常见,java中一般把最近最少使用的对象先释放。
一一一、iOS7之前,后台执行内容有几种形式,都是什么?
1、一般的应用在进入后台的时候可以获取一定的时间来运行相关任务,也就是说可以在后台运行一小段时间(10s左右)
2、后台播放音乐、后台GPS跟踪、后台voip支持
一一二、简单说明App的启动过程?
1、第一种情况:有storyboard
A:程序入口main函数
B:UIApplicationMain;创建UIApplication对象,创建UIApplication的delegate对象
C:根据info.plist加载Main storyboard file base name所执行的storyboard
D:创建UIWindow,创建和设置UIWindow的根控制器rootViewController,显示窗口
2、第二种情况:没有storyboard
A:程序入口main函数
B:UIApplicationMain;创建UIApplication对象,创建UIApplication的delegate对象
C:delegate对象开始监听系统事件,程序启动完毕时调用代理的application:didFinishLaunchingWithOptions:方法,在该方法中创建窗口,设置根控制器,显示窗口
一一三、有些图片加载的比较慢如何处理?
1、图片下载要放下异步线程执行
2、图片下载过程中使用占位图片
3、如果图片较大,可以考虑使用断点下载
一一四、你实现过一个框架或者库以供别人使用么?如果有,请谈一谈构建框架或者库时候的经验;如果没有,请设想和设计框架的public的API,并指出大概需要如何做、需要注意一些什么方面,来使别人容易地使用你的框架?
1、提供给外界的接口功能是否充足够用
2、别人使用我的框架时能够根据类名方法名猜出大概能实现的功能
3、别人调用框架的接口时提供的参数是否够用,调用起来是否简单
4、当使用我的框架时要不要依赖其他的框架
一一五、App需要加载大量的数据,给服务器发送请求时,服务器卡住了怎么解决?
1、设置请求超时
2、提示用户请求超时
3、根据用户操作再次请求数据
一一六、AFN和ASI有什么区别?
1、底层实现:AFN的底层基于OC的NSURLConection和NSURLSession
ASI的底层基于纯C语言的CFNetwork框架,ASI的性能高于AFN
2、对服务器返回数据的处理:AFN提供多种处理方式JSON/XML等
ASI没有提供处理方式,直接返回二进制数据
3、处理请求的方式:AFN采用block的方式,监听请求成功或失败
ASI最初采用的是代理的方式进行处理,后面也相应增加了block的方式
4、功能:AFN只封装一个一些常用功能,满足基本需求
ASI提供的功能较多,如控制菊花在请求过程中的转动、设置请求间的依赖、统一管理所有请求等;还预留了很多接口供开发者自行扩展
5、文件下载和上传的使用难易度:AFN不太容易监听下载和上传进度,不容易实现断点续传,一般只用来下载较小的文件
ASI在这些方法都比较容易的实现
6、注意:ASI几年前已经停止更新,所以现在使用AFN的还是占大多数
一一七、网络数据处理过程中,发现某部分比较卡,一般怎么解决?
1、检查网络请求操作是否被放在主线程了
2、检查异步请求的数量是不是太多(子线程数量)
3、查看是不是因为数据量过大造成的卡顿,如果是可以先清理一些不必要的对象(看不见的数据、图片)
4、查看手机cpu的使用率和内存使用
一一八、怎么解决sqlite锁定的问题?
1、设置数据库锁定的处理函数int sqlite3_busy_handler(sqlite3*,
int()(void,int), void*);
2、设定锁定时的等待时间int sqlite3_busy_timeout(sqlite3*, 60);
一九、简单介绍isa指针?
1、在OC中任何类的定义都是对象,类和类的对象没有本质的区别,任何对象都有isa指针
2、isa就是一个Class类型的指针。每个实例对象都有一个isa的指针,并指向该对象所属的类
一二零、OC有私有方法吗?私有变量呢?
1、OC是一种动态消息传递机制,所有本质上不存在真正意义上的私有方法
2、但是,如果方法只在.m中实现而不在.h中进行声明,或者说在.m文件的ClassExtension中声明,可以算作是私有方法
3、私有变量可以通过@private修饰实现私有
一二一、如何提升ios程序的性能?
1、使用ARC去管理内存
2、适当的地方使用重用机制reuseIndentifier
3、避免使用臃肿的xib
4、使用延时加载
5、选择合适的数据存储方式,不合理的存储方式也是耗性能的
6、对于内存警告要及时处理
7、使用自动释放池
8、缓存,缓存,缓存,如图片、UITableView的行高
9、不要在主线程做一些耗时繁重的操作
10、选择正确的数据格式,常用JSON和XML
一二二、用预处理指令#define声明一个常数,用来表示一年有多少秒(忽略闰年问题)?
1、#defineSECONDS_PER_YEAR(60 * 60 * 24* 365) UL
2、注意不能以分号结尾,#和define中间不能有任何东西,UL表示无符号长整型
附:预处理主要内容:宏定义(#define)、条件编译(#ifdef/#else/#endif)、文件包含(#incldue)
一二三、写一段程序将字符串"ILove .Chinese"反转成"ChineseLove I"?
1、先用componentsSeparatedByString:方法通过.将字符串分成ILove和Chinese保存到数组array1中
2、在用该方法利用空格将I和Love分割保存到数组array2中
3、最后拼接字符串array1[1] + array2[1] + array2[0]
附:字符串常用函数:-(NSString
*)substringFromIndex: (NSUInteger)from;含义:从指定位置from开始到尾部(包括指定位置的字符)
-(NSString *)substringToIndex:
(NSUInteger)to;含义:从字符串开始截取,截取到指定的位置to(不包含指定位置的字符)
-(NSString *)substringWithRange:
(NSRange)range;含义:按照所给出的范围从字符中截取,且包含指定位置的字符
-(NSString *)stringByReplacingOccurrentsOfString:(NSString *)target
withString:(NSString*)replacement;
含义:用replacement代替target
-(unichar)characterAtIndex:(NSUInteger)index;返回index位置对应的字符
-(BOOL) hasPrefix:(NSString
*)aString;检查字符串是否以某个字符串开头,Suffix结尾
一二四、简要说明const关键字?
1、概念:const是一个类型修饰符,使用const修饰的变量可以让变量的值不能被修改,也可以修饰函数的参数和返回值
2、作用:A:使变量不可变,保护被修饰的东西,防止意外修改,增强健壮性
B:便于进行类型检查
C:节约内存空间,避免不必要的内存分配
3、使用技巧:修饰常指针时:先看“*”的位置
A:如果const在*的左侧表示值不能修改,但是指向可以改。
B:如果const在*的右侧表示指向不能改,但是值可以改
C:如果在“*”的两侧都有const标识指向和值都不能改。
一二五、简单介绍下cocoatouch框架?
1、CocoaTouch是苹果公司提供的软件开发api(类库),用于开发iPhone、iPad等设备
2、CocoaTouch由多个框架组成:
UIKit框架负责启动和结束应用程序,控制界面和多触点事件
CoreAnimation提供强大的动画效果
CoreAudio提供播放处理和录制音频等技术
CoreData提供数据管理的解决方案
其他的如MapKit(地图)、Address Book(电子邮件、联系人)使用也很广泛
一二六、写一个NSString类的实现?
1、+ (id)initWithCString:(const char
*)nullTerminatedCString encoding:(NSStringEncoding)encoding;
- (id) stringWithCString: (constchar*)nullTerminatedCString
encoding: (NSStringEncoding)encoding
{
NSString *obj;
obj = [selfallocWithZone: NSDefaultMallocZone()];
obj = [obj initWithCString:nullTerminatedCString encoding: encoding];
return AUTORELEASE(obj);
}