1.你如何看待iOS中的拷⻉贝
在我看来,⽇日常⽣生活中,当我们⽤用到”拷⻉贝”这个词语的时候,不管怎样都
会产⽣生两份。⼀一份是原来的,⼀一份是新拷⻉贝出来的。但是到⺫⽬目前为⽌止,在
iOS中我看到了三种拷⻉贝⽅方式:
(1)伪拷⻉贝:伪拷⻉贝,顾名思义,就是假拷⻉贝,没有拷⻉贝出新的对象。这
⼀一点对于NSString这种类簇来说⽐比较常⻅见,NSString本⾝身是不可变字符
串,内容不可能被修改,因此我们也没有拷⻉贝的必要,因为拷⻉贝的⺫⽬目的是
防⽌止原件被修改,所以才拷⻉贝出来⼀一份,伪拷⻉贝实际上是对象引⽤用计数加
了1(相当于retain或者strong的功效)。
(2)浅拷⻉贝:浅拷⻉贝就是确实拷⻉贝出来⼀一份和原来内容⼀一样的新对象。但
是对于对象⾃自带的属性是伪拷⻉贝,两个对象的属性指向同⼀一个内存。
(3)深拷⻉贝:深拷⻉贝就是不仅仅拷⻉贝出⼀一份新对象,⽽而且对象的属性也拷
⻉贝了⼀一份。
总的来说,如果在开发的过程中需要实现拷⻉贝,那么需要接受NSCopying
协议。实现copyWithZone:⽅方法。浅拷⻉贝、深拷⻉贝的区别在于
copyWithZone:⽅方法的实现不同。
2.@synthesize和@dynamic有什么区别
(1)@property有两个对应的词,⼀一个是@synthesize,⼀一个是
@dynamic。如果@synthesize和@dynamic都没写,那么默认的就是
@syntheszie var = _var;
(2)@synthesize的语义是如果你没有⼿手动实现setter⽅方法和getter⽅方法,
那么编译器会⾃自动为你加上这两个⽅方法。
(3)@dynamic告诉编译器:属性的setter与getter⽅方法由⽤用户⾃自⼰己实现,
不⾃自动⽣生成。(当然对于readonly的属性只需提供getter即可)。假如
⼀一个属性被声明为@dynamic var,然后你没有提供@setter⽅方法和
@getter⽅方法,编译的时候没问题,但是当程序运⾏行到instance.var =
someVar,由于缺setter⽅方法会导致程序崩溃;或者当运⾏行到 someVar
= instance.var时,由于缺getter⽅方法同样会导致崩溃。编译时没问题,
运⾏行时才执⾏行相应的⽅方法,这就是所谓的动态绑定。@dynamic可⽤用于
在分类中添加属性(需要⽤用到objc_getAssociatedObject和
objc_setAssociatedObject函数)。
3.ARC下dealloc⽅方法存在的意义在于什么地⽅方?
其实在MRC中dealloc⽅方法存在的主要意义是为了释放⾃自⾝身的实例变量,
移除观察者,停⽌止timer,移除通知,代理置空等。ARC下,系统会帮助
我们释放该对象所包含的实例变量,但是有些对象还是需要们⾃自⼰己去释放
的(⽐比如Core Foundation框架下的⼀一些对象
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];//
移除通知观察者
scrollView.delegate = nil;
[timer invalidate];
}
4.分别下厨MRC中在assign、retain、copy下属性name对应的setter⽅方法
assign下
- (void) setName:(NSString*)name
{
_name = name;
}
retain下
- (void) setName:(NSString*)name
{
if(_name != name){
[_name release];
_name = [name retain];
}
}
copy下
- (void) setName:(NSString*)name
{
if(_name != name){
[_name release];
_name = [name copy];
}
}
5.如何实现程序后台运⾏行?
苹果是不赞成程序在后台运⾏行的(因为很费电),除⾮非后台运⾏行能提升⽤用
户体验。有3种情况允许程序后台运⾏行。
(1)在前台开启了⼀一个短任务,可以在程序进⼊入后台的时候,向系统申请
点时间把任务执⾏行完。
(2)前台有下载任务,可以在进⼊入后台的时候继续下载。
(3)⼀一些特定类型的任务可以在后台运⾏行,⽐比如:定位,⾳音乐播放,VoIP
等等。
对于第⼀一种情况,可以调⽤用UIApplication类的
beginBackgroundTaskWithName:expirationHandler:或者
beginBackgroundTaskWithExpirationHandler:⽅方法申请⼀一点额外的时
间去执⾏行未完成的任务。调⽤用这两个⽅方法中的⼀一个都会临时延迟应⽤用程序
进⼊入休眠的时间,以便有时间把任务执⾏行完。当任务执⾏行完毕之后,应⽤用
程序需要调⽤用endBackgroundTask:⽅方法让系统知道任务执⾏行完了,程
序可以进⼊入休眠状态了。不⼀一定⾮非得等应⽤用程序要进⼊入后台了才设置后台
需要执⾏行的任务。⼀一个好的设计应该是在任务开始前就是⽤用
beginBackgroundTaskWithName:expirationHandler:或者
beginBackgroundTaskWithName:expirationHandler:添加后台执⾏行的
任务,任务⼀一旦执⾏行完就调⽤用endBackgroundTask:⽅方法告诉后台,需
要进⼊入后台执⾏行的任务执⾏行完了(此时可能还没进⼊入后台)。
对于第⼆二种情况,如果要下载⽂文件,应⽤用程序应该使⽤用NSURLSession对
象去开启下载任务,这样系统就可以在程序休眠的时候控制下载,当我们
配置NSURLSession需要在后台传输的时候,系统会单独开⼀一个进程去处
理下载任务,如果在下载的时候,进⼊入了后台,会在后台继续下载。想要
实现后台下载,我们需要配置NSURLSession。⾸首先创建⼀一个
NSURLSessionConfiguration对象,设置⼀一些属性,然后把
NSURLSessionConfiguration对象设置给NSURLSession对象。具体步骤:
(1)使⽤用backgroundSessionConfigurationWithIdentifier:创建
NSURLSessionConfiguration对象。(2)设置NSURLSessionConfiguration
对象的sessionSendsLaunchEvents 属性为YES。(3)如果在前台已经开始
下载了,还需要设置NSURLSessionConfiguration的discretionary属性
为YES。(4)为NSURLSessionConfiguration对象设置其他你需要的属性。
(5)把NSURLSessionConfiguration对象设置给NSURLSession对象。
第三种情况属于Long-Running任务。如果需要实现⻓长时任务,必须去申
请,⽽而且只有特定的类型才能⻓长时间在后台执⾏行。⽐比如:后台播放⾳音频,
后台录⾳音,后台定位和导航,VoIP,定期下载和处理新内容,定期接收
外设的数据。需要在Info.plist添加UIBackgroundModes字段选择需要后
台运⾏行的事件类型,或者在⼯工程的Capabilities⾥里⾯面打开Background
Modes,勾选对应的事件,告诉系统会在后台运⾏行什么类型的Long-
Running任务,然后再根据不同类型的事件做相应的处理即可。
6.⽤用OC些⼀一个冒泡排序
NSMutableArray *numbers = [@[@42, @75, @22, @14, @1, @55]
mutableCopy];
for (int i = 0; i < numbers.count - 1; i++) {
for (int j = 0; j < numbers.count - 1 - i; j++) {
if ([numbers[j] integerValue] > [numbers[j + 1] integerValue])
{
[numbers exchangeObjectAtIndex:j withObjectAtIndex:j +
1];
}
}
}
7.id声明的对象有什么特性
id是任意对象类型的,不能表⽰示基本类型。id类型是通⽤用指针类型,因为
通过指针,也就是内存地址来引⽤用对象,所以可以将任意对象赋值给id类
型的对象。返回id类型值的⽅方法是返回指向内存中某对象的指针。然后可
以将该值赋给任何对象变量(强制类型转换即可)。因为⽆无论在哪⾥里,对
象总是携带它的isa成员。所以即使将它存储在id类型的通⽤用对象变量中,
也总是可以确定它的真实类型,id是多态的⼀一种体现。
8.简单描述⼀一下Runloop在实际开发中的应⽤用场景
NSTimer中常常⽤用到,例如说我们在做动画的时候,开辟在⼦子线程中执⾏行
动画,甚⾄至是连锁动画,不停地调⽤用Runloop可以使我们的动画连贯的执
⾏行完毕,另外⼀一种情况也出现在Timer当中,就是我们的tableview和轮
播图⾃自动滚动同时出现时,滑动tableview,轮播图不会继续⾛走,可以使
⽤用runloop⼀一直执⾏行timer的⽅方法。
9.什么是懒加载?在使⽤用懒加载时的注意事项是什么?
所谓的懒加载指的是延迟创建对象,只有当需要的时候才创建对象。在真
正开发的过程中其实懒加载就是重写getter⽅方法。在getter⽅方法的内部,
实现对象的创建,如果对象为nil才创建,如果不为nil,直接返回对象。在
真正使⽤用懒加载时需要注意的是当第⼀一次使⽤用对象时,需要调⽤用self.因为
只有这样才能调⽤用对应的getter⽅方法,对象才会被创建。
10.iOS中有哪些数据持久化的⽅方式,各有什么特点?iOS平台怎么做数据的持久化?
iOS中可以有四种持久化数据的⽅方式: 属性列表、对象归档、SQLite3和
Core Data;Core Data可以使你以图形界⾯面的⽅方式快速的定义app的
数据模型,同时在你的代码中容易获取到它。core data提供了基础结构
去处理常⽤用的功能,例如保存,恢复,撤销和重做,允许你在app中继续
创建新的任务。在使⽤用Core Data的时候,你不⽤用安装额外的数据库系统,
因为core data使⽤用内置的sqlite数据库。Core Data将你app的模型层
放⼊入到⼀一组定义在内存中的数据对象中。Core Data会追踪这些对象的改
变,同时可以根据需要做相反的改变,例如⽤用户执⾏行撤销命令。当Core
Data在对你app数据的改变进⾏行保存的时候,Core Data会把这些数据
归档,并永久性保存。
mac os X中sqlite库,它是⼀一个轻量级功能强⼤大的关系数据引擎,也很容
易嵌⼊入到应⽤用程序。可以在多个平台使⽤用,sqlite是⼀一个轻量级的嵌⼊入式
sql数据库编程。与core data框架不同的是,sqlite是使⽤用程序式的,sql
的主要的API来直接操作数据表。
Core Data不是⼀一个关系型数据库,也不是关系型数据库管理系统
(RDBMS)。虽然Core Dta⽀支持SQLite作为⼀一种存储类型,但它不能使⽤用
任意的SQLite数据库。Core Data在使⽤用的过程中⾃自⼰己创建这个数据库。
Core Data⽀支持对⼀一、对多的关系。