一、strong与weak,unsafe_unretained
1.strong:强引用,引用计数+1
2.weak:弱引用,当指针指向的地址一旦被释放,这些指针将被赋值为nil ,防止引起野指针;
strong与weak是arc引入的,类似于非arc下的retain与assign
放风筝:strong相当于风筝线,weak相当于风筝的影子
unsafe _unretained: 声明一个弱应用,但是不会自动nil化,也就是说,如果所指向的内存区域被释放了,这个指针就是一个野指针了。
二、#import、#include和@class有什么区?
#import 系统文件,自定义文件引用 自动只导入一次 不会重复导入
#include 和 #import 几乎一样 但是他需要注意不能重复引用
@class 只是告诉系统有这个类,但是如果在实现类中用到这个类需要重新用 #import导入该类头文件
三、类变量@private,@protected,@public,@package,声明各有什么含义
@private:作用范围只能在自身类
@protected:作用范围在自身类和继承自己的子类
@public:作用范围最大,可以在任何地方被访问
@package:这个类型最常用于框架类的实例变量,同一包内能用,跨包就不能访问
四、IOS本地数据存储有哪几种方式?
NSKeyedArchiver:归档形式保存数据,遵守NSCoding协议
NSUserDefaults:应用程序设置和属性,用户保存的数据
Write写入:永久保存到磁盘中
Sqlite (FMDB):FMDB中小型数据库
Coredata
五、IOS沙盒
1.每个应用程序都有自己的存储空间
2.每个应用程序都不可以翻过自己的围墙去访问别的存储空间的内容
3.在访问别人沙盒内的数据时需要访问授权
速记口诀:阿爹太老了
Doucuments:
app运行中建立的/app应用程序中浏览到的文件数据保存在该目录下.(iTunes会自动备份该目录)
Temp: 用于存放临时文件,当app退出后不再需要的文件
Library:
Caches:缓存文件,保存应用再次启动时需要的信息。
Perferences:偏好设置文件(iTunes会自动备份该目录)
五、深拷贝与浅拷贝的理解
浅拷贝:指针拷贝,同一对象
深拷贝:对象拷贝,不同对象
总结:
浅复制好比你和你的影子,你完蛋,你的影子也完蛋
深复制好比你和你的克隆人,你完蛋,你的克隆人还活着
六、什么事序列化和反序列化,可以用来做什么?如何在oc中实现复杂对象的存储?
序列化是把对象转化成字节序列的过程 反序列化是把字节序列恢复成对象
将对象写到文件或者数据库里,并且能读取出来
遵循NSCoding协议,实现复杂对象的存储 实现该协议后可以对其进行打包或解包,转化成NSData
七、简述应用程序按Home键进入后台时的生命周期,以及从后台回到前台时的生命周期?
将进入后台时
-(void)applicationWillResignActive:(UIApplication *)application;
-(void)applicationDidEnterBackground:(UIApplication *)application;
进入前台时
-(void)applicationDidEnterForeground:(UIApplication *)application;
-(void)applicationWillResignActive:(UIApplication *)application;
八.、viewcontroller的alloc loadView,viewDidLoad,viewWillAppear,viewWillDisAppear,viewDidAppear,viewDidDisAppear,viewDidUnload,dealloc,init分别是在什么时候调用的?
alloc申请内存时调用
loadView加载试图时调用
viewDidLoad视图已经加载后调用
ViewWillAppear视图将要渲染时调用
ViewWillDisAppear视图渲染结束时调用
ViewDidUnload视图已经加载但没有加载出来调用
dealloc销毁该视图时调用
init视图初始化时调用
九、UIImageview初始化一张图片有几种方法?简述各自的优缺点。
imgeNamed:系统会先检查系统缓存中是否有改名字的imge,如果有的话,则直接返回,如果没有,则先加载图片到缓存,然后再返回;
initWithContensOfFile:系统不会检查系统缓存,而直接从文件系统中加载并返回;
11.类别(categories)和拓展(extensions)为什么Category只能为对象添加方法,却不能添加成员变量?
Category:类别
1.为已经存在的类添加方法(不能添加属性,不能增删)
2.声明私有方法
3.将类的实现分散到多个不同文件
运行时决定的,不可以添加实例变量,对象的内存布局已经确定,不可能破坏类的内存布局
Extension:拓展 私有的category
1.给类添加私有方法 只为自己类所见所使用
2.可以添加属性,且添加的方法是必须要实现的
编译时决定的,可添加实例变量。类的一部分,伴随类的产生而产生,消失消失而消失
备注:在上线的项目更新中 用类别比继承更能维护项目的稳定性
12.什么事懒汉模式(lazy loading)
用到的时候才去初始化,也可以理解成延迟加载。
一个延时加载,避免内存过高
一个异步加载,避免线程堵塞
14.简述你对UIView、UIWindow和CALayer的理解
15.ViewController 的 didReceiveMemoryWarning 是在什么时候被调用的?
当应用程序的内存使用接近系统的最大内存使用时,应用会向系统发送内存警告,程序收到内存警告时候ViewController会调用 didReceiveMemoryWarning这个方法
16.看下面的程序,第一个NSLog会输出什么?找时str的retain count 是多少?第二个和第三个呢?为什么
18.谈谈你对多线程开发的理解?IOS中有几种实现多线程的方法?
好处:
1.把占据时间长的程序中的任务放到后台去处理
2.程序的运行速度可能加快
3.体验更加友好
缺点:
1.如果有大量的线程,会影响性能,因为操作系统需要在它们之间切换
2.更多的线程需要更多的内存空间
3.线程的中止需要考虑其对程序运行的影响
十九.多线程
19.手势与响应链
Button > 手势-Tap > 响应链-TouchBegin ->TouchEnd
事件响应链:UIButton - UIView - UIViewController - UIWindow - UIApplication - AppDelegate
响应者:iOS中能够响应事件的对象都是UIResponder的子类对象。UIResponder提供了四个用户点击的回调方法,分别对应用户点击开始,移动,点击结束以及取消点击,其中只有在程序强制退出或者来电时,取消点击事件才会调用
1.手势操作是大哥,点击事件响应链是小弟 【Tap > 响应链】
2.单击事件优先传递给手势响应,如果手势识别成功便取消了响应链传递,如果手势识别失败事件会继续传递给响应链
3.手势识别需要时间,有可能响应链已经处理了部分步骤
经典案例:如何不让父视图手势识别干扰子视图 ?
20.代理为什么使用weak?
1.如果使用strong scrollview.delegate=self (self代表控制器)
2.当控制器想要销毁时,控制器被强指针指着(self被scrollview.delegate指着)
3.scrolview添加到视图控制器的view也被强指针指着,无法销毁,那么他的delegate不会销毁;
delegate指向控制器,造成了循环引用。
4.把delegate变成weak; 当控制器生命周期结束时,view随之销毁,delegate也就销毁了
二十一.离屏渲染
1.当屏渲染:在当前用于显示的屏幕缓冲区进行渲染操作
2.离屏渲染:GPU或CPU在当前屏幕缓冲区以外新开辟一个缓冲区进行渲染操作,过程要切换Contests上下文
GPU产生离屏渲染主要是CALayer使用圆角,阴影,遮罩
CPU产生离屏渲染主要是CoreGraphics核心绘图导致
二十二、堆 与 栈
栈是吃了吐,堆是吃了拉 堆栈的本质是内存管理
栈是系统提供的数据结构,堆C/C++函数库提供的
1.栈:由系统编译器自动管理,不需要程序员管理
堆:由程序员手动管理,不及时回收会导致内存泄漏
2.栈:动态分配 与静态分配
堆:动态分配和回收内存
125. UIView如何需要重新绘制整个界面,需要调用什么方法?
UIView setNeedsDisplay和setNeedsLayout方法,两个方法都是异步执行的。
1.setNeedsDisplay会调用自动调用drawRect方法,这样可以拿到UIGraphicsGetCurrentContext,就可以画画了。
2.setNeedsLayout会默认调用layoutSubViews,就可以处理子视图中的一些数据。
setNeedsDisplay方便绘图,而layoutSubViews方便出来数据
setNeedDisplay告知视图它发生了改变,需要重新绘制自身,就相当于刷新界面