分别写出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];
}
}
ARC环境下的delloc具体存在的意义在于什么地方?举例说明具体的s会用场景.
其实在MRC环境中delloc存在的意义是为了释放自己的实例变量,移除观察者,代理置空,停止timer等,但是在ARC环境下,系统已经帮助释放了该对象所包含的实例对象.当然了像一些Core Foundation对象还是需要自己进行手动释放的.那么delloc在ARC环境下的具体作用就是移除观察者,代理置空,停止timer.
如何看待iOS中的拷贝?
在我看来,我们日常iOS开发过程中的拷贝一共有两种,一种是深拷贝,另外一种则是浅拷贝.
(1)浅拷贝:浅拷贝实际上就是只拷贝指向对象的指针,并不会拷贝对象本身,也就是说浅拷贝和原来的指针是指向同一块内存地址的.
(2)深拷贝:深拷贝拷贝的则是对象的本身,所以拷贝前后的两个指针只想的内存地址是不一样的.
系统都有哪些单例类?在实际开发过程中,单例的应用场景在于什么地方?
答:系统为我们提供了很多单例类,比如NSUserDefaults、UIApplication、UIScreen、UIDevice、NSNotificationCenter、NSFileManager等等.而且在实际开发过程中,除了使用系统给我们提供的单例类之外,还会根据需求自己创建类.
例如,
1.数据库处理.对于数据的增删改查,可能在很多界面都会用到,那这个时候,我们可以定义一个针对数据处理的单例类.
2.音乐播放.在音乐播放类项目,一般在多个页面都需要音乐播放,所有,我们可以写一个音乐播放的单例类.
3.下载管理,当下载音乐或者视频的时候,我们应该创建一个单例类来管理下载任务.
4.登录注册类,当一个应用有登录注册的时候,我们应给创建一个单例类来管理登录者的用户信息和登录状态.
程序在启动的时候主要做了什么操作?
应用程序在启动的时候,会首先执行main函数,而在main函数当中会执行UIApplicationMain函数,UIApplicationMain函数主要做了如下的三个事情.
1.创建并且初始化一个UIApplication对象.
2.创建应用程序代理对象,系统默认的是AppDelegate.
3.创建一个事件循环RunLoop,用来实时监测应用的各种事件(触摸,晃动,通知,观察者,timer等)
简述ViewController的几个生命周期.
1.-(instancetype)init: 初始化方法
2.-(void)loadView: 加载根式图
3.-(void)viewDidLoad: 根式图已经加载完成.
4.-(void)viewWillAppear: 视图将要出现.
5.-(void)viewDidAppear:视图已经出现.
6.-(void)viewWillDisappear:视图将要消失.
7.-(void)viewDidDisappear:视图已经消失.
8.-(void)delloc:释放观察者,timer关闭,代理置空.
UIImage初始化一个图片的方法以及优缺点.
UIImage初始化一张图片最常用的一共有三个方法,分别是是imageNamed:、imageWithContentesOfFile:、imageWithData:.
(1)imageNamed:: 这个方法创建的时所需要的图片是从缓存中获取的,先在缓存中查找是否有该图片,如果没有,那么会将图片加进缓存中再使用,如果有这张图片,那么直接使用缓存中的,这个方法创建UIImage对象主要是用于图片重复率比较高,当然了,这个方法也是有弊端的,那就是一旦将图片加入缓存当中,这张图片就不会被释放掉了.
(2)imageWithContentesOfFile::这个方法是直接从本地沙盒中获取, 并不会结果缓存,主要是用于重复率不是很高的图片,使用这种方式.
(3)imageWithData:: 这种方式可以使用本地的网络数据也可以使用本地的二进制数据.但是这种方式会造成线程卡顿,所以建议放在子线程中进行实现.
block在定义成属性应该用什么关键字?为什么?
block在定义成属性的时候应该使用copy修饰,平常我们使用的block主要是存放在栈区的(有的也会存放在全局区).栈区的block出了作用域之后就会被释放掉,如果我们在block释放掉之后还继续调用,那么就会出现crash.理论上,在全局区的block我们是不需要进行copy的.但是大部分的block是存储在栈区的,为了统一规范管理,所以我们都使用copy对block属性进行修饰.
谈谈你对block和delegate的认识.
无论使用block还是delegate本质上都是回调.使用block,其优势是回调的block代码块直接放在block赋值位置,使代码更加紧凑,但是使用block需要注意循环引用问题,需要使用__weak和__block两个修饰符来解决循环引用问题;delegate不能像block做特殊处理,但是如果多个对象设置的代理为一个对象,那么就需要在delegate中判断一下到底是哪一个对象了.
什么是沙盒?
所谓沙盒就是操作系统为应用程序分配的一个文件夹.应用程序拥有这个文件夹的访问权限,且只能对这个文件夹内的文件进行操作.(当然也能访问系统提供的文件夹,比如相册),对其他应用程序文件夹没有访问权限.
定义属性的时候,什么情况使用copy、assign和retain?
assign用于简单数据类型,如NSInteger、Bool、double等.copy和retain用于对象类型,不过copy是用于一个对象可能被修改,但是不想修改原件,所以拷贝一份出来(新拷贝的对象引用计数为1);这样新拷贝的修改了,原件不会被修改,同样,原件被修改了,新拷贝的不会被修改.retain则是引用计数加1,对象只有一个,并不会进行复制拷贝.
简述应用程序按Home键进入后台时的生命周期,以及从后台进入前台的生命周期.
正在运行的程序点击Home键的时候,程序由活跃状态变为非活跃状态.之后程序就进入后台.在这个过程中执行了两个方法分别是applicationWillResigeActive和applicationDidEnterBackground.
当程序从后台进入前台的时候,应用程序由非活跃状态变为活跃状态,这个期间也执行了两个方法分别为applicationWillEnterForeground和applicationDidBecomeActive.
在使用一些系统的类例如UITableView时,会发现其delegate属性设置为assign而不是retain,这是为什么?
使用assign而不使用retain的原因在于避免产生循环引用问题,如果使用retain修饰delegate的话,那么当通过set方式赋值的时候,引用计数会加1,这样到最后会造成循环引用,而assign是直接赋值,并不会引起引用计数的增加,因此使用assign并不会造成内存泄露.
当手指点击屏幕上的登录按钮,响应者链的检测过程是什么样子的?
当手指触摸到屏幕上的登录按钮,首先runloop检测到触摸事件,将事件传递给UIApplication对象,UIApplication对象将事件传递给AppDelegate对象,AppDelegate对象将事件传递给window对象,之后就是rootViewController,接着就是view,之后检测view上的子视图,通过比对找到触摸的Button.
沙盒中一共有几个文件夹,请简述它们的作用?
沙盒之中一共有三个文件夹,分别是Documents、Library和Tmp.
Documents: 苹果建议将程序中建立的或程序中浏览的文件数据保存到该目录下,ITunes备份和恢复时候包含此目录.
Library: 程序中默认设置或者是其他状态信息.
Library/Caches:存放缓存文件,一般是下载的图片或视频,iTunes不会备份此目录,此目录不会再在程序退出时删除.
Tmp: 临时文件夹,应用程序会在重启的时候,删除该文件夹下的所有内容.
在OC中引入头文件使用的关键字是哪一个?能在C语言文件中使用吗?
#import是OC中引入头文件所使用的关键字,在C语言中不能使用;#include是OC和C语言中能引入头文件共同使用的关键字.
#import和#include相比,好处是什么?
使用#import可以避免重复导入头文件问题,而使用#include需要注意重复导入问题,因此在OC中都是使用#import来导入头文件.
#import <>和#import " "相比,区别是什么?
#import <>用于系统文件的引用,编译器会在系统文件目录查找文件.
#import " "用于自定义文件的引用,编译器首先在用户目录下查找,接着是安装目录,最后是系统目录.
@class的作用是什么?
@class的作用是告诉编译器@class后面跟的是一个类名.只是告诉编译器有这个类名,类中具体还有什么方法并没有提及,也就说不会导入类中的内容.经常在头文件中使用.
多线程的优点和缺点分别是什么?
优点:1.将耗时较长的事件放在子线程中,防止主线程被卡死.2.可以发挥多核处理的能力,提高cpu的使用率.
缺点:1.每开辟一个县城就会造成一定的资源损耗.2.会造成代码可读性变差.3.如果出现多个线程访问一个资源,会造成资源抢夺现象.
NSOperationQueue有一个属性叫maxConcurrentCount即最大并发数,这里的最大并发数是什么含义?
这里的最大并发数是指在队列中同时执行的任务的个数.
iOS中数据持久化都有哪些方式,各有什么特点.iOS平台如何做数据持久化的,CoreData和sqlite有无必然的联系?CoreData是一个关系型数据库吗?
在iOS中有四种数据持久化方式,分别是属性列表、数据归档、sqlite3数据库、CoreData.
CoreData数据库可以使用图形界面快速定义app的数据模型,同时在你的代码中容易获取到它.CoreData提供了基础结构去处理常用的功能.,例如保存,恢复,撤销和重做.允许你在app中创建新的任务.在使用CoreData数据库的时候,你不需要安装额外的数据库系统,因为CoreData使用内置的sqlite数据库.CoreData将你的模型层放入一组在内存的数据对象中,CoreData会跟中这些对象的变化,同时需要作出相反的变化,例如用户执行撤销命令.当CoreData在你app数据的改变进行保存的时候,CoreData会把这些数据归档,并永久性保存.
CoreData不是一个关系型数据库,虽然CoreData执行SQLite作为一种存储类型,但它不能使用任意SQLite数据库.CoreData在使用过程中自己创建这个数据库.CoreData支持一对一、一对多的关系.
什么是懒加载?在使用懒加载的时候应该注意什么?
所谓的懒加载指的是延时创建对象.只有在需要的时候才去创建对象,在真正开发过程当中,懒加载其实是重写了getter方法,在getter方法中,实现对象的创建.如果对象为nil的时候才会创建,如果不为nil,直接返回对象.在真正使用懒加载的时候需要使用self.进行调用,这样才能调用属性的getter方法.
什么叫RunTime.
Runtime就是运行时,一个程序开发过程当中通常分为以下几个阶段,编辑-预编译-编译-连接-运行,RunTime就是我们程序在运行阶段发生的一些事情,在这一个阶段通常会把OC代码转化为C代码,从而提高运行效率.系统给我们提供了runtime的类库,我们可以通过里面的方法实现OC方法到C函数的转化,也可以给分类添加属性.类库中都有对应的方法.
简单描述一下RunLoop在实际开发过程中的场景.
比如一个页面中同时轮播图和tableView时候,在滑动tableView的时候,轮播图是不动的.这时候我将轮播图中的NSTimer加入RunLoop中.
再例如,在一个子线程中开启另外的一个子线程现在图片,却发现下载任务并没有执行.这时候需要将下载图片的任务代码放入RunLoop中去.
简单描述一下SDWebImage的原理和实现机制,以及SDWebImage的底层实现。
原理:
1、显示占位图。
2、在内存缓存中查找图片是否已经下载,如果现在那么久回调显示。
3、如果内存缓存中没有,生产NSInvocationOperation添加到队列中去磁盘中查找,如果有那么久添加到内存中并且回调显示。
4、如果磁盘中没有,那就使用下载器进行下载,下载完成之后同时在你磁盘中和存缓存中保存并且回调显示,写到文件中也要单独的使用NSInvocationOperation完成,避免拖慢主线程。
5、SDImageCache会在初始化的时候注册一些消息通知,在内存警告或者退到后台的时候清理内存图片缓存,退出程序的时候回清理过期的图片。
实现机制:代理模式
底层实现原理:沙河缓存机制,主要是由(内存图片缓存,内存操作缓存,磁盘沙河缓存)
调用一个类的静态方法需不需要release?
调用一个雷的静态方法不需要ralease,其实静态成员方法也是有对象的,叫做类对象。胆这个类对象在第一次访问类成员的时候就会将其加载到内存的,而且该类对象只在程序关闭的时候才会释放,并不需要我们进行管理。
简述__weak和__block修饰符的区别。
1、__block修饰符不管是在ARC还是MRC环境下都可以使用,还可以修饰基本数据类型。
2、__weak只能在ARC环境下使用,也只能修饰对象,不能修饰基本数据。
3、被__block修饰的对象在block中可以重新被赋值,但是__weak不可以。
作者:神经骚栋
链接:http://www.jianshu.com/p/ceeea029a1d0
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。