iOS面试题整理---[难度]***
[U]推送的原理
1、注册:为应用程序申请消息推送服务。此时你的设备会向APNs服务器发送注册请求。 2、APNs服务器接受请求,并将deviceToken返给你设备上的应用程序 3、客户端应用程序将deviceToken发送给后台服务器程序,后台接收并储存。 4、后台服务器向APNs服务器发送推送消息 5、APNs服务器将消息发给deviceToken对应设备上的应用程序
[U]KVO的实现原理
参考:
https://www.jianshu.com/p/703aafde0c4
https://www.jianshu.com/p/e59bb8f59302
https://tech.glowing.com/cn/implement-kvo/[自己实现KVO]
https://www.jianshu.com/p/703aafde0c40[自己实现KVO]
基本的原理:
当观察某对象 A 时,KVO 机制动态创建一个对象A当前类的子类,并为这个新的子类重写了被观察属性 keyPath 的 setter 方法。setter 方法随后负责通知观察对象属性的改变状况。
深入剖析:
Apple 使用了 isa 混写(isa-swizzling)来实现 KVO 。当观察对象A时,KVO机制动态创建一个新的名为:NSKVONotifying_A 的新类,该类继承自对象A的本类,且 KVO 为 NSKVONotifying_A 重写观察属性的 setter 方法,setter 方法会负责在调用原 setter 方法之前和之后,通知所有观察对象属性值的更改情况。 (备注: isa 混写(isa-swizzling)isa:is a kind of ; swizzling:混合,搅合;)
①NSKVONotifying_A 类剖析:在这个过程,被观察对象的 isa 指针从指向原来的 A 类,被 KVO 机制修改为指向系统新创建的子类 NSKVONotifying_A 类,来实现当前类属性值改变的监听;所以当我们从应用层面上看来,完全没有意识到有新的类出现,这是系统“隐瞒”了对 KVO 的底层实现过程,让我们误以为还是原来的类。但是此时如果我们创建一个新的名为“NSKVONotifying_A”的类,就会发现系统运行到注册 KVO 的那段代码时程序就崩溃,因为系统在注册监听的时候动态创建了名为 NSKVONotifying_A 的中间类,并指向这个中间类了。
(isa 指针的作用:每个对象都有 isa 指针,指向该对象的类,它告诉 Runtime 系统这个对象的类是什么。所以对象注册为观察者时,isa 指针指向新子类,那么这个被观察的对象就神奇地变成新子类的对象(或实例)了。) 因而在该对象上对 setter 的调用就会调用已重写的 setter,从而激活键值通知机制。
—>我猜,这也是 KVO 回调机制,为什么都俗称KVO技术为黑魔法的原因之一吧:内部神秘、外观简洁。
②子类setter方法剖析:KVO 的键值观察通知依赖于 NSObject 的两个方法:willChangeValueForKey:和 didChangevlueForKey:,在存取数值的前后分别调用 2 个方法:
被观察属性发生改变之前,willChangeValueForKey:被调用,通知系统该 keyPath 的属性值即将变更;当改变发生后,
didChangeValueForKey: 被调用,通知系统该 keyPath 的属性值已经变更;之后, observeValueForKey:ofObject:change:context: 也会被调用。且重写观察属性的 setter 方法这种继承方式的注入是在运行时而不是编译时实现的。
KVO 为子类的观察者属性重写调用存取方法的工作原理在代码中相当于:
-(void)setName:(NSString *)newName{
[self willChangeValueForKey:@"name"]; //KVO 在调用存取方法之前总调用
[super setValue:newName forKey:@"name"]; //调用父类的存取方法
[self didChangeValueForKey:@"name"]; //KVO 在调用存取方法之后总调用
}
[U]Swift的优缺点?
序列化: 将数据结构或对象转换成二进制串的过程。 反序列化:将在序列化过程中所生成的二进制串转换成数据结构或者对象的过程。序列化与反序列化操作同属于类NSJSONSerialization。
序列化:
将Json对象转化为Json字符串
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:jsonObj options:NSJSONWritingPrettyPrinted error:&error];
NSString *jsonStr = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
反序列化:
服务器返回JSON字符串JsonStr,将其转换为Foundition Object。
NSData *jsonData = [jsonStr dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *resultDic1 = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:nil];
#include<stdio.h> #include<string.h> #define PRAISE "My name is Bai Jiangwei" int main(void) { char name[40] = "BaiJiangWei"; printf("%u %u \n",strlen(name),sizeof(name)); printf("%u %u \n",strlen(PRAISE),sizeof(PRAISE)); } //运行结果 11 40 23 24 Press any key to continue //结论 1.对于一个字符串变量,strlen()的结果是字符串本身的长度,在本例中BaiJiangWei长度为11;而sizeof(name)的结果是该字符串变量在定义时的长度,
在本例中char name[40],故sizeof(name)结果为40 2.对于一个字符串常量,我们定义时并没有定义其长度,所以strlen()的结果就是字符串本身长度,而sizeof()的结果是strlen()+1,多出来的长度1,实际上就是\0 --------------------- 作者:纪晓岚爱coder 来源:CSDN 原文:https://blog.csdn.net/weixin_37815691/article/details/82886973 版权声明:本文为博主原创文章,转载请附上博文链接!
可以自定义View:https://github.com/zhengwenming/WMDragView
我们举个简单的例子: 文件1:3,6,9 文件2:2,4,8 文件3:1,5,7 第一回合: 文件1的最小值:3 , 排在文件1的第1行 文件2的最小值:2,排在文件2的第1行 文件3的最小值:1,排在文件3的第1行 那么,这3个文件中的最小值是:min(1,2,3) = 1 也就是说,最终大文件的当前最小值,是文件1、2、3的当前最小值的最小值,绕么? 上面拿出了最小值1,写入大文件.第二回合: 文件1的最小值:3 , 排在文件1的第1行 文件2的最小值:2,排在文件2的第1行 文件3的最小值:5,排在文件3的第2行 那么,这3个文件中的最小值是:min(5,2,3) = 2 将2写入大文件. 也就是说,最小值属于哪个文件,那么就从哪个文件当中取下一行数据.(因为小文件内部有序,下一行数据代表了它当前的最小值)
[U]简单介绍加壳,混淆,安全,逆向,hook等???
[U]如果你要将一个大文件进行拷贝,你能想到哪些可能存在的问题?(拷贝中编辑文件、拷贝太久影响主界面、显示进度、拷贝时应用切到后台、拷贝时应用被系统杀死)针对这些问题你如何解决?
[U]哈希表如何处理冲突
https://www.cnblogs.com/kwklover/articles/837942.html
[U]Autolayout底层实现???
[U]异常是如何收集的,底层的原理是什么???
T