以下内容是题主最近几天的总结,没有特定的顺序,看到了不错的知识点就记录了下来,分享给需要的小伙伴们,另外题主第一次写这么多文字内容(虽然大部分网上都有,我只是一个小小的搬运工),有表达不对的地方,欢迎指正,十分感激。
1.NSInteger有什么特点?
是基本数据类型Int或者Long的别名(NSInteger的定义typedef long NSInteger),它的区别在于,NSInteger会根据系统是32位还是64位来决定是本身是int还是Long。
2.Id 声明的对象有什么特性?
Id 声明的对象具有运行时的特性,即可以指向任意类型的objcetive-c的对象;
3.Objective-C的内存管理主要有哪几种方式?
Objective-C的内存管理主要有三种方式ARC(自动内存计数)、手动内存计数、内存池。
4.内存管理的几条原则时什么?
谁申请,谁释放
5.如何对iOS设备进行性能测试?
Profile-> Instruments ->Time Profiler
6.线程间通信的方法
[self performSelectorOnMainThread:@selector(test) withObject:nil waitUntilDone:NO];
dispatch_async(dispatch_get_main_queue(), ^{ });
7.类别的作用:
(1)将类的实现分散到多个不同文件或多个不同框架中。
(2)创建对私有方法的前向引用。
(3)向对象添加非正式协议。
8.oc中的协议和java中的接口概念有何不同?
OC中的协议有2层含义,官方定义为 formal和informal protocol。前者和Java接口一样。informal protocol中的方法属于设计模式考虑范畴,不是必须实现的,但是如果有实现,就会改变类的属性。其实关于正式协议,类别和非正式协议我很早前学习的时候大致看过,也写在了学习教程里“非正式协议概念其实就是类别的另一种表达方式“这里有一些你可能希望实现的方法,你可以使用他们更好的完成工作”。这个意思是,这些是可选的。比如我门要一个更好的方法,我们就会申明一个这样的类别去实现。然后你在后期可以直接使用这些更好的方法。这么看,总觉得类别这玩意儿有点像协议的可选协议。"现在来看,其实protocal已经开始对两者都统一和规范起来操作,因为资料中说“非正式协议使用interface修饰“,现在我们看到协议中两个修饰词:“必须实现(@requied)”和“可选实现(@optional)”。OC中的协议(formal protocol)与java中的接口概念基本一致,OC中非正式协议(informal protocol)就是类别。在java中如果继承了接口,但不实现其方法,会得到一个error(无法编译);在OC中的正式协议,如果不实现,会得到一个warning(可编译执行),如果想去除waring,还可以加关键字(@optional),让它可选实现方法。
9.What are KVO and KVC?
kvc:键 - 值编码是一种间接访问对象的属性使用字符串来标识属性,而不是通过调用存取方法,直接或通过实例变量访问的机制。很多情况下可以简化程序代码。
kvo:键值观察机制,他提供了观察某一属性变化的方法,极大的简化了代码。
10.kvo能观察实例变量么?
关于kvo的原理有很多,主要是用到了kvc和Method Swizzling,大家可以搜索下,对于观察实例变量其实分为下面两种:
1)有访问器方法
运行时会重写访问器方法调用will/didChangeValueForKey:方法。
因此,直接调用访问器方法改变属性值时,KVO也能监听到。
2)没有访问器方法,显示调用will/didChangeValueForKey:方法。
运行时会在setValue:forKey方法中调用will/didChangeValueForKey:方法
总之,想使用KVO,只要有will/didChangeValueForKey:方法就可以了。
11.代理的作用?
代理的目的是改变或传递控制链。允许一个类在某些特定时刻通知到其他类,而不需要获取到那些类的指针。可以减少框架复杂度。
12.我们说的oc是动态运行时语言是什么意思?
多态,主要是将数据类型的确定由编译时,推迟到了运行时。
这个问题其实浅涉及到两个概念,运行时和多态。
简单来说,运行时机制使我们直到运行时才去决定一个对象的类别,以及调用该类别对象指定方法。
多态:不同对象以自己的方式响应相同的消息的能力叫做多态。意思就是假设生物类(life)都拥有一个相同的方法-eat;
那人类属于生物,猪也属于生物,都继承了life后,实现各自的eat,但是调用是我们只需调用各自的eat方法。
也就是不同的对象以自己的方式响应了相同的消息(响应了eat这个选择器)。
因此也可以说,运行时机制是多态的基础?~~~
13.UIScrollview的实现原理
利用了view的bounds,bounds就像scrollview的contentsize,修改了bounds后,在scrollview上面的子视图的原点就会改变,手动设置手势就可以实现scrollview.
14.NSArray与NSMutableArray是线程安全的么?
NSArray是线程安全的,NSMutableArray不是线程安全的,多线程使用到NSMutableArray需要注意。
15.类NSObject的那些方法经常被使用?
NSObject是Objetive-C的基类,其由NSObject类及一系列协议构成。其中类方法alloc、class、 description 对象方法init、dealloc、– performSelector:withObject:afterDelay:等经常被使用
16.什么是简便构造方法?
答案:简便构造方法一般由CocoaTouch框架提供,如NSNumber的+ numberWithBool:+ numberWithChar:+ numberWithDouble:+ numberWithFloat:+ numberWithInt:Foundation下大部分类均有简便构造方法,我们可以通过简便构造方法,获得系统给我们创建好的对象,并且不需要手动释放
17.什么是谓词?
答案:谓词是通过NSPredicate,是通过给定的逻辑条件作为约束条件,完成对数据的筛选。predicate = [NSPredicate predicateWithFormat:@"customerID == %d",n];a = [customers filteredArrayUsingPredicate:predicate];
18.如何捕获崩溃?
NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler);
19.响应链
First Responser --> The Window -->The Applicationn --> App Delegate
2.当一个子view需要接收点击事件,其父view也需要接收点击事件,该如何处理:
按照正常情况下,子类接收点击事件以后,事件不会主动传递到下一个响应者,因此父类便不再接收点击事件。如果子类不处理点击事件,则事件会一直传递下去,直到UIApplication。
但是我们可以使得子类处理过响应事件后仍将响应这传递到下一个响应者。但是我们编写代码才能办到。
子view的代码如下:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
// 这里可以做子view自己想做的事,做完后,事件继续上传,就可以让其父类,甚至父viewcontroller获取到这个事件了
[[self nextResponder]touchesBegan:toucheswithEvent:event];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
[[self nextResponder]touchesEnded:toucheswithEvent:event];
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event{
[[self nextResponder] touchesCancelled:toucheswithEvent:event];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
[[self nextResponder] touchesMoved:toucheswithEvent:event];
}
20.protocolbuffer (这个可以作为简单了解,题主之前用过,所以看了下)
一,protocolbuffer(以下简称PB)是google 的一种数据交换的格式,它独立于语言,独立于平台。google 提供了多种语言的实现:java、c#、c++、go 和python,每一种实现都包含了相应语言的编译器以及库文件。由于它是一种二进制的格式,比使用xml进行数据交换快许多。可以把它用于分布式应用之间的数据通信或者异构环境下的数据交换。作为一种效率和兼容性都很优秀的二进制数据传输格式,可以用于诸如网络传输、配置文件、数据存储等诸多领域。
二,Protobuf的优点1,性能好,效率高2,代码生成机制,数据解析类自动生成3,支持向后兼容和向前兼容4,支持多种编程语言(java,c++,python)5,参考文档:http://blog.csdn.net/caisini_vc/article/details/5599468
三,Protobuf的缺点1, 应用不够广2, 二进制格式导致可读性差(二进制格式)3, 缺乏自描述
21.为什么objective-c称之为objective-c.
NSObject 是一个结构体
struct NSObject{
Class isa;
}; 所有的object都是c的结构体
22.你对NSUrlsession的了解?
NSURLSessionDataTask, NSURLSessionUploadTask, 和NSURLSessionDownloadTask,支持后台操作,支持断点续传,会话.
共享会话避免每次都三次TCP握手,支持http2.0速度更快
23.timer什么时候释放
当一个timer被schedule的时候,timer会持有target对象,NSRunLoop对象会持有timer。当invalidate被调用时,NSRunLoop对象会释放对timer的持有,timer会释放对target的持有。除此之外,我们没有途径可以释放timer对target的持有。所以解决内存泄露就必须撤销timer,若不撤销,target对象将永远无法释放,dealloc里面没法撤销,因为不会走dealloc方法,所以要在viewwilldisapper里面调用[timer invalidate];
24.写一个标准宏MIN
#define MIN(A,B) ((A) <= (B)?(A):(B))
25.OC最大的优点缺点
优点:运行时特性。
缺点:没有命名空间,对于命名冲突,可以使用长命名法或特殊前缀解决,如果是引入的第三方库之间的命名冲突,可以使用link命令及flag解决冲突
26.NSOperation与GCD的优缺点
NSOperation和NSOperationQueue是多线程的面向对象抽象。项目中使用NSOperation的优点是NSOperation是对线程的高度抽象,在项目中使用它,会使项目的程序结构更好,子类化NSOperation的设计思路,是具有面向对象的优点(复用、封装),使得实现是多线程支持,而接口简单,建议在复杂项目中使用NSOperation
27.SDwebimage是如何清除缓存的?
注册了三个通知,收到内存警告清除内存,程序被杀死UIApplicationWillTerminateNotification清除硬盘,程序进入后台清除硬盘。
清除机制:文件的缓存有效期及最大缓存空间大小。文件的缓存有效期可以通过maxCacheAge属性来设置,默认是1周的时间。如果文件的缓存时间超过这个时间值,则将其移除。而最大缓存空间大小是通过maxCacheSize属性来设置的,如果所有缓存文件的总大小超过这一大小,则会按照文件最后修改时间的逆序,以每次一半的递归来移除那些过早的文件,直到缓存的实际大小小于我们设置的最大使用空间。清理的操作在-cleanDiskWithCompletionBlock:方法中
28.常用加密算法的了解(我也一知半解)
MD5:把东西加密成一串数字
Base64:
转码过程例子:
3*8=4*6
内存1个字符占8位
转前: s 1 3
先转成ascii:对应 115 49 51
2进制: 01110011 00110001 00110011
6个一组(4组)011100110011000100110011
然后才有后面的 011100 110011 000100 110011
然后计算机是8位8位的存数 6不够,自动就补两个高位0了
所有有了 高位补0
科学计算器输入00011100001100110000010000110011
得到 28 51 4 51
查对下照表 c z E z
把三个字节的分成四个字节,每个字节补2个0
SHA:该算法的思想是接收一段明文,然后以一种不可逆的方式将它转换成一段(通常更小)密文,也可以简单的理解为取一串输入码(称为预映射或信息),并把它们转化为长度较短、位数固定的输出序列即散列值(也称为信息摘要或信息认证代码)的过程。散列函数值可以说是对明文的一种“指纹”或是“摘要”所以对散列值的数字签名就可以视为对此明文的数字签名.
与MD5相似 都是不可逆
29.多线程的锁
NSLock的执行原理:某个线程A调用lock方法。这样,NSLock将被上锁。可以执行“关键部分”,完成后,调用unlock方法。如果,在线程A 调用unlock方法之前,另一个线程B调用了同一锁对象(关键是同一个实例lock)的lock方法。那么,线程B只有等待。直到线程A调用了unlock
30.gzip压缩(可以看些网络方面的知识)
减小文档的一个方式就是在服务端和你的app中打开gzip。这对于文字这种能有更高压缩率的数据来说会有更显著的效用,能大大减少网络传输的数据量,提高了用户显示网页的速度。当然,同时会增加一点点服务器的开销.
31.iOS性能优化
tableview优化,
Instruments的使用,
NSDateFormatter,
imageWithContentsOfFile,
如果一个方法在一个循环次数非常多的循环中使用,在进入循环前使用 methodForSelector 获取该方法 IMP,然后在循环体中直接使用该 IMP
32.pthread
跨平台,适用于多种操作系统,可移植性强
是一套纯C语言的通用API,且线程的生命周期需要程序员自己管理,使用难度较大,通常不使用
33.离屏渲染
houldRasterize(光栅化),masks(遮罩),shadows(阴影),edge antialiasing(抗锯齿),group opacity(不透明),复杂形状设置圆角等,渐变,当使用圆角,阴影,遮罩的时候,图层属性的混合体被指定为在未预合成之前不能直接在屏幕中绘制,所以就需要屏幕外渲染被唤起
34.UIView CALayer
UIView本身,更像是一个CALayer的管理器,访问它的根绘图和根坐标有关的属性,例如frame,bounds等 等,实际上内部都是在访问它所包含的CALayer的相关属性
35.如何反转一个数组的内容
for (var i = 0; i < arr.length / 2; i++) {
var temp = arr[i]; //交换变量
arr[i] = arr[arr.length - i - 1];
arr[arr.length-i-1]=temp;
}
36.数组和链表
数组是将元素在内存中连续存放,由于每个元素占用内存相同,可以通过下标迅速访问数组中任何元素。但是如果要在数组中增加一个元素,需要移动大量元素,在内存中空出一个元素的空间,然后将要增加的元素放在其中。同样的道理,如果想删除一个元素,同样需要移动大量元素去填掉被移动的元素。如果应用需要快速访问数据,很少或不插入和删除元素,就应该用数组。
链表恰好相反,链表中的元素在内存中不是顺序存储的,而是通过存在元素中的指针联系到一起。比如:上一个元素有个指针指到下一个元素,以此类推,直到最后一个元素。如果要访问链表中一个元素,需要从第一个元素开始,一直找到需要的元素位置。但是增加和删除一个元素对于链表数据结构就非常简单了,只要修改元素中的指针就可以了。如果应用需要经常插入和删除元素你就需要用链表数据结构了。
37.以下代码输出什么?
1.dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"A");
});
2.NSLog(@"B");
dispatch_queue_tqueue_tmp = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,0);
3.dispatch_sync(queue_tmp, ^{
NSLog(@"C");
});
4.dispatch_async(queue_tmp, ^{
NSLog(@"D");
});
5.dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"E");
});
6.[self performSelector:@selector(test)withObject:nil afterDelay:0.0];
7.NSLog(@"F");
- (void)test
{
NSLog(@"G");
}
一开始以为因为里面有异步,所以打印的顺序有可能会变,后来发现打印的顺序恒为:BCFDGAE
1.dispatch_async(dispatch_get_main_queue()) 这个方法是在主线程添加一个方法执行,但是viewdidload是在添加的方法之前,所以要等后面的语句执行完,才走新添加的方法。
2.dispatch_sync(queue_tmp, ^{ 这个方法会阻塞当前线程 肯定是顺序执行
3.dispatch_async(queue_tmp, ^{ 这个方法是异步 立即执行 且不影响下面的方法
4.[self performSelector:@selector(test)withObject:nil afterDelay:0.0]; 当前方法内任务执行完后才执行,所以是最后执行(不知是否会估任务量(test方法执行需要的时间) 因为测试发现顺序不一致,任务量大的话 放后面执行 任务量小的话放前面执行)
5.除非是阻塞当前线程 否则都是先走接下来的代码
38.以下代码输出什么?
int a=5;
int b=3;
int c=3;
int d=0;
d =a*(b++) - c;
NSLog(@"%d %d",d,b);
12 4,b先进行赋值,然后自身加1.
39.post 相比get 有很多优点,为什么现在的HTTP通信中大多数请求还是使用get?
好吧, 除了哲学方式的回答以外,下面是一个浏览器从业人员的看法
事实上GET 和 POST 在实践上面有非常大的区别,这两种方法在语义上面并非能互相取代。
POST 是否比 GET 安全
是的, POST要比GET安全一点点,注意,是一点点。。。
说这两者都是明文传送当然是没有错的了,但是这里有一个细节,就是GET的URL会被放在浏览器历史和WEB 服务器日志里面。
POST 发完基本就木有了。。
所以如果你把关键数据放在GET里面,被人偷窥了浏览器,或者WEB服务器被入侵日志被人倒去了,基本泄露可能性100%。而POST来说,日志没有记录,只要数据库服务器不被入侵,基本还是安全的。
当然如果被抓了包,这一切都没有什么卵用,所以,HTTPS该用还是得用
GET 相对 POST 的优势是什么
最大的优势是, GET 的URL可以人肉手输啊。。。你在地址栏打个POST给我看看。本质上面, GET 的所有信息都在URL, 所以很方便的记录下来重复使用。
所以如果你希望
- 请求中的URL可以被手动输入
- 请求中的URL可以被存在书签里,或者历史里,或者快速拨号里面,或者分享给别人。
- 请求中的URL是可以被搜索引擎收录的。
- 带云压缩的浏览器,比如Opera mini/Turbo 2, 只有GET才能在服务器端被预取的。
- 请求中的URL可以被缓存。
请使用GET.
大家有没有注意到,其实这里面很多方面的要求是和网站的运营相关的,而不是技术相关的。任何的技术行为中,其实多多少少都能看到商业的影子。
反之,就用POST. 特别是有一些东西你是不想让人家可以在浏览器地址栏里面可以输入的。比如,如果你设计一个blog系统, 设计这样一个URL来删掉所有帖子。
http://myblog.com/?action=delete_all
我只能说很快你就知道什么叫不作死就不会死这个道理了,搜索引擎的爬虫分分钟教你做人。
另外一个准则是,可以重复的交互,比如取个数据,跳个页面, 用GET.
不可以重复的操作, 比如创建一个条目/修改一条记录, 用POST, 因为POST不能被缓存,所以浏览器不会多次提交。
WEB API 的设计相对于网页来说更加复杂,同时也有GET/POST的问题,目前主流接受的方法是RESTful, 参见这里
-----------------------------------------------------未完待续,本文会持续更新