得物
KVO willchangevalue什么时候调用
键值观察通知依赖于 NSObject 的两个方法: willChangeValueForKey: 和 didChangevlueForKey:;在一个被观察属性发生改变之前, willChangeValueForKey: 一定会被调用,这就 会记录旧的值。而当改变发生后,didChangeValueForKey: 会被调用,继而 observeValueForKey:ofObject:change:context: 也会被调用。
CocoPod install和update有什么区别
使用pod update PODNAME可以去更新一个库的指定版本(检查相应的库是否存在更新的版本,并且更新),相对应的,使用pod install将不会更新那些已经下载安装了的库。
当你在Podfile中添加了一个新的库时,你应该使用pod install命令,而不是pod udpate,这样安装了新增的库,也不会重复安装已经存在的库。
使用pod update仅仅只是去更新指定库的版本(或者全部库)。
Pod文件干嘛用的
lock文件是干嘛用的
Podfile.lock 文件记录所有已安装的代码库的描述.其结构如下
造成死锁的四个条件
自旋锁和递归锁的区别
自旋锁(spinlock):
同样用来标记只能有一个线程访问该对象,在同一线程多次加锁操作会造成死锁;使用硬件提供的swap指令或test_and_set指令实现;同互斥锁不同的是在锁操作需要等待的时候并不是睡眠等待唤醒,而是循环检测保持者已经释放了锁,这样做的好处是节省了线程从睡眠状态到唤醒之间内核会产生的消耗,在加锁时间短暂的环境下这点会提高很大效率
递归锁(recursivelock):
严格上讲递归锁只是互斥锁的一个特例,同样只能有一个线程访问该对象,但允许同一个线程在未释放其拥有的锁时反复对该锁进行加锁操作; windows下的临界区默认是支持递归锁的,而linux下的互斥量则需要设置参数PTHREAD_MUTEX_RECURSIVE_NP,默认则是不支持
Nslock是什么锁
NSLock是互斥锁
Nslock里面加Nslock
NSLock是非递归锁,当同一线程重复获取同一非递归锁时,就会发生死锁,可以用递归锁代替NSLock,比如NSRecursiveLock或者@synchronized
atomic 安全吗?用的什么锁
因为atomic做了线程锁,所以理论上讲atomic是要比nonatomic更加耗费性能、更慢。
atomic 系统会在生成的setter/getter方法里添加锁,但是这个锁仅仅是保证了setter/getter存取的安全,并不能保证数据结果正确 , 用的互斥锁spinlock_t是os_unfair_lock
信号量里面加信号量有什么问题
监听卡顿怎么监听的,为什么在beforewaiting
为什么在主线程刷新UI 子线程也可以刷新UI
因为UIKit框架不是线程安全的,当多个线程同时操作UI的时候,抢夺资源,导致崩溃,UI异常等问题
OS中只有主线程才能立即刷新UI。在子线程中是不能够更新UI,我们看到的子线程能够更新UI的原因是,等到子线程执行完毕,自动进入了主线程去执行子线程中更新UI的代码。由于子线程执行时间非常短暂,让我们误以为子线程可以更新UI。如果子线程一直在运行,则无法更新UI,因为没有办法进入主线程。
runloop 是一个循环吗
在main中 子线程调用不会执行
FMDB用的什么线程
FMDatabaseQueue
weak怎么处理
weak属性什么时候销毁
是通过objc_loadWeak方法进行的。而根据 Clang的官方文档,objc_loadWeak方法会retain并autorelease这个对象。所以给一个weak对象赋值,它并不会马上释放,而是会放到autorelease pool中,与autorelease pool一起释放。
自动释放池原理
自己写autorelease和不写autoreleas有什么区别
手动干预释放机制:指定autoreleasepool,就是所谓的作用域大括号结束释放;
系统自动释放:不手动指定autoreleasepool。
autorelease对象除了作用域后,会被添加到最近一次创建的自动释放池中,并会在当前的runloop迭代结束时释放。
ps:runloop从程序启动到加载完成是一个完整的运行循环,然后会停下来,等待用户交互,用户的每一次交互都会启动一次运行循环,这时候会创建自动释放池,来处理用户所有的点击事件、触摸事件,在一次完整的运行循环结束之前,会销毁自动释放池,达到销毁对象的母的
并行 串行
信号量是什么锁
锁是服务于共享资源的;而semaphore是服务于多个线程间的执行的逻辑顺序的。
字典用的什么hash表
hash碰撞怎么解决的,放在减1的位置,为什么
打包用的ipa是怎么加壳
网易云盾
一个字典里面存储10000个数据,怎么快速找到
Nsoperation里面的KVO是怎么监听的,源码看过吗
Afnet取消是怎么处理的,这个时候可能服务器有响应,或者没响应
2.0和3.0区别
2.0使用的NSURLConnection,3.0使用的是NSURLSession,
1)NSURLConnection下载文件时,先是将整个文件下载到内存,然后再写入到沙盒,如果文件比较大,就会出现内存暴涨的情况。而使用NSURLSessionUploadTask下载文件,会默认下载到沙盒中的tem文件中,不会出现内存暴涨的情况。
2)NSURLConnection停止请求的发送,停止后不能继续访问,需要创建新的请求。NSURLSession有三个控制方法,取消(cancel)、暂停(suspend)、继续(resume),暂停以后可以通过继续恢复当前的请求任务。
3)AFN3.0 NSURLSession 不需要2.0NSURLConnection 的常驻线程。
2.0需要常驻线程是因为请求回调依赖当前线程,而AFN3.0 NSURLSession的请求回调不需要依赖当前线程,可以指定回调的delegateQueue,这样也就不需要再对线程进行保活。
内存五大分区: 栈区、堆区、全局区、常量区、代码区
实现一个读写锁
runloop 的三个阶段
B站面试
锁忘了释放,怎么办,怎么处理,比如oc的try cache
二进制协议 多工 数据流 头信息压缩 服务器推送
下面代码有什么问题
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
//变量存在寄存器中
@autoreleasepool {
__block NSObject *obj = nil;
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0), ^{
while (YES) {
NSLog(@"%@", [obj description]);
}
});
while (YES) {
obj = [NSObject new];
NSLog(@"new obj");
}
}
return 0;
}
阿里
大数据存储
用事物
国密算法 都有哪些
- 国密即国家密码局认定的国产密码算法。主要有SM1,SM2,SM3,SM4。密钥长度和分组长度均为128位。
- SM1 为对称加密。其加密强度与AES相当。该算法不公开,调用该算法时,需要通过加密芯片的接口进行调用。
- SM2为非对称加密,基于ECC。该算法已公开。由于该算法基于ECC,故其签名速度与秘钥生成速度都快于RSA。ECC 256位(SM2采用的就是ECC 256位的一种)安全强度比RSA 2048位高,但运算速度快于RSA。
- 国家密码管理局公布的公钥算法,其加密强度为256位
- SM3 消息摘要。可以用MD5作为对比理解。该算法已公开。校验结果为256位。
- SM4 无线局域网标准的分组数据算法。对称加密,密钥长度和分组长度均为128位。
平安
mutableCopy进行自定义对象拷贝
- 1.让类实现NSCopying/NSMutableCopying协议。
- 2.让类实现copyWithZone:/mutableCopyWithZone:方法
为分类添加关联属性,怎么添加一个weak的 属性默认的是atomic
字符串用等号可以判断吗 相同字符串,创建地址相同
- 等于号比较的是地址 isEqualToString可以判断
计算属性,可以节省资源
- 当第一次调用的时候,会调,如果属性里面的值一直不变,则计算属性不会再调用
百度
内存管理,引用计数,什么时候不是0
一个ip地址,怎么转成int,且,可以变回字符串
AFN和原生的请求有什么区别 内存管理 weak修饰可选型 unown修饰非可选型,有区别的
哈罗面试
autorelease 什么时候释放
一般情况下,每个接受autorelease消息的对象,都会在下个runloop开始前被释放。也就是说,在一段同步的代码中执行过程中,生成的对象接受autorelease消息后,一般是不会在作用域结束前释放的。
所以严谨的说, 在没有手动添加Autorelease Pool的情况下,Autorelease对象是在当前的runloop迭代结束时释放的,而它能够释放的原因是系统在每个runloop迭代中都加入了自动释放池Push和Pop。
点击事件扩大范围
重写方法 -(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event
重写方法 - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
事件响应
系统通过 IOKit.framework来处理硬件操作,其中屏幕处理也通过IOKit完成(IOKit可能是注册监听了屏幕输出的端口)
当用户操作屏幕,IOKit收到屏幕操作,会将这次操作封装为IOHIDEvent对象。通过mach port(IPC进程间通信)将事件转发给SpringBoard来处理。SpringBoard是iOS系统的桌面程序。SpringBoard收到mach port发过来的事件,唤醒main runloop来处理。
SpringBoard的main runloop将事件交给当前应用程序的source1处理,这时候会唤醒当前应用程序的runloop,当前应用程序的source1会调用__IOHIDEventSystemClientQueueCallback()函数,该函数内部会判断,是否有程序在前台显示,如果有则通过mach port将IOHIDEvent事件转发给这个程序。
如果前台没有程序在显示,则表明SpringBoard的桌面程序在前台显示,也就是用户在桌面进行了操作。__IOHIDEventSystemClientQueueCallback()函数会将事件交给source0处理,source0会调用__UIApplicationHandleEventQueue()函数,函数内部会做具体的处理操作。
例如用户点击了某个应用程序的icon,会将这个程序启动。
应用程序接收到SpringBoard传来的消息,会唤醒main runloop并将这个消息交给source1处理,source1调用__IOHIDEventSystemClientQueueCallback()函数,在函数内部会将事件交给source0处理,并调用source0的__UIApplicationHandleEventQueue()函数。
在__UIApplicationHandleEventQueue()函数中,会将传递过来的IOHIDEvent转换为UIEvent对象。在函数内部,将事件放入UIApplication的事件队列,等到处理该事件时,将该事件出队列,UIApplication将事件传递给窗口对象(UIWindow),如果存在多个窗口,则从后往前询问最上层显示的窗口
窗口UIWindow通过hitTest和pointInside操作,判断是否可以响应事件,如果窗口UIWindow不能响应事件,则将事件传递给其他窗口;若窗口能响应事件,则从后往前询问窗口的子视图。
以此类推,如果当前视图不能响应事件,则将事件传递给同级的上一个子视图;如果能响应,就从后往前遍历当前视图的子视图。
如果当前视图的子视图都不能响应事件,则当前视图就是第一响应者。
找到第一响应者,事件的传递的响应链也就确定的。
如果第一响应者非UIControl子类且响应链上也没有绑定手势识别器UIGestureRecognizer;
那么由于第一响应者具有处理事件的最高优先级,因此UIApplication会先将事件传递给它供其处理。首先,UIApplication将事件通过 sendEvent: 传递给事件所属的window,window同样通过 sendEvent: 再将事件传递给hit-tested view,即第一响应者,第一响应者具有对事件的完全处理权,默认对事件不进行处理,传递给下一个响应者(nextResponder);如果响应链上的对象一直没有处理该事件,则最后会交给UIApplication,如果UIApplication实现代理,会交给UIApplicationDelegate,如果UIApplicationDelegate没处理,则该事件会被丢弃。
如果第一响应者非UIControl子类但响应链上也绑定了手势识别器UIGestureRecognizer;
UIWindow会将事件先发送给响应链上绑定的手势识别器UIGestureRecognizer,再发送给第一响应者,如果手势识别器能成功识别事件,UIApplication默认会向第一响应者发送cancel响应事件的命令;如果手势识别器未能识别手势,而此时触摸并未结束,则停止向手势识别器发送事件,仅向第一响应者发送事件。如果手势识别器未能识别手势,且此时触摸已经结束,则向第一响应者发送end状态的touch事件,以停止对事件的响应。
如果第一响应者是自定义的UIControl的子类同时响应链上也绑定了手势识别器
UIGestureRecognizer;这种情况跟第一响应者非UIControl子类但响应链上也绑定了手势识别器UIGestureRecognizer`处理逻辑一样;如果第一响应者是UIControl的子类且是系统类(UIButton、UISwitch)同时响应链上也绑定了手势识别器UIGestureRecognizer;
UIWindow会将事件先发送给响应链上绑定的手势识别器UIGestureRecognizer,再发送给第一响应者,如果第一响应者能响应事件,UIControl调用调用sendAction:to:forEvent:将target、action以及event对象发送给UIApplication,UIApplication对象再通过 sendAction:to:from:forEvent:向target发送action。
GCD怎么取消
iOS8之后可以调用dispatch_block_cancel来取消(需要注意必须用dispatch_block_create创建dispatch_block_t,dispatch_block_cancel也只能取消尚未执行的任务,对正在执行的任务不起作用。)
定义外部变量,用于标记block是否需要取消
autorelease和runloop什么关系
NSRunloop是一个消息循环,会监测输入源(inputsource)和定时源(timer source)。apple官方文档(多线程编程指南)描述: "run loop 是用来在线程上管理事件异步到达的基础设施......run loop在没有任何事件处理的时候会把它的线程置于休眠状态,它消除了消耗CPU周期轮询,并防止处理器本身进入休眠状态并节省电源。"消除CPU空转是它最大的作用。
Runloop的重点是:
1.用来监听长耗时异步事件,例如网络回调,苹果原生和第三方用的都是Runloop。
2.消除CPU空转。
每个线程都有一个默认的NSRunloop,主线程中的NSRunloop默认是运行的,非主线程中的NSRunloop默认是没有运行的,通常需要为NSRunloop添加一个事件然后去运行。一般情况下没有必要去启动一个线程的NSRunloop,除非需要长久的去监测某个异步事件。举个具体的例子,NSURLConnection网络数据请求,默认是异步的方式,其创建原理就是创建之后将其作为事件源加入当前的Runloop,而等待网络响应的过程是在一个新建的独立的线程中完成,当这个线程处理到某个阶段比如收到响应后便通知之前的线程去执行相应的delegate方法。
对于每一个runloop,Entry事件(即将进入Loop),其回调内会调用 _objc_autoreleasePoolPush() 创建自动释放池,这样所有的AutoreleasePool会构成一个像CallStact一样的栈式结构,在每一个Runloop结束时,Exit(即将退出Loop)调用_objc_autoreleasePoolPop() ,当前栈顶的AutoreleasePool会被销毁,这样这个Pool里面的每个object都有被release。所以runloop 和AutoReleasepool是通过线程的方式一一对应的
有arc了为啥还需要autoreleasepool
ARC 并不是舍弃了 @autoreleasepool,而是在编译阶段帮你插入必要的 retain/release/autorelease 的代码调用。
所以,跟你想象的不一样,ARC 之下依然是延时释放的,依然是依赖于 NSAutoreleasePool,跟非 ARC 模式下手动调用那些函数本质上毫无差别,只是编译器来做会保证引用计数的正确性。
用@autoreleasepool是有用的。
正常情况下,你创建的变量会在超出其作用域的时候被释放掉。
而如果你的函数写的很长,在你函数运行过程中出现很多中间变量,占据了大量的内存,怎么办?
用@autoreleasepool。
在@autoreleasepool中创建的变量,会在@autoreleasepool结束的时候执行一次release,进行释放。其实@autoreleasepool就相当于一层作用域。
Https 是怎么通信的
HTTPS通信主要包括几个节点,发起请求、验证身份、协商秘钥、加密会话,具体流程如下(此例子只有客户端对服务端的单向验证):
1、客户端向服务端发起建立HTTPS请求。
2、服务器向客户端发送数字证书。
3、客户端验证数字证书,证书验证通过后客户端生成会话密钥(双向验证则此处客户端也会向服务器发送证书)。
4、服务器生成会话密钥(双向验证此处服务端也会对客户端的证书验证)。
5、客户端与服务端开始进行加密会话。
Block里面什么时候要强引用一下
如果函数执行过程中self变为nil了,那么函数一开始声明的strongSelf会暂时持有着self,此时会有一个暂时的引用循环。当函数执行完(即是Block执行完),strongSelf超出作用域被释放,引用循环从这里开始打破。接下来,由于没有任何强引用持有self了,于是self被释放,最后Block也因为没有任何强引用持有它也被释放了。所有对象就都被顺利释放了。
__weak 和__strong 一定要成对出现吗? 举个例子
__weak修饰的对象被Block引用,不会影响对象的释放,而__strong在Block内部修饰的对象,会保证,在使用这个对象在scope内,这个对象都不会被释放,出了scope,引用计数就会-1,且__strong主要是用在多线程运用中,若果只使用单线程,只需要使用__weak即可
抓包需要证书吗? 需要
怎么抓取微信的包
Https 安全吗? 不安全怎么办
哈罗二面
KVO是多线程的吗,同步还是异步
将修改对象属性过程放在子线程内执行,在监听回调方法内获取当前线程同样为子线程.故KVO的响应和KVO观察的值变化是在一个线程上的.
一个需要注意的地方是,KVO 行为是同步的,并且发生与所观察的值发生变化的同样的线程上。没有队列或者 Run-loop 的处理。手动或者自动调用 -didChange... 会触发 KVO 通知。
所以,当我们试图从其他线程改变属性值的时候我们应当十分小心,除非能确定所有的观察者都用线程安全的方法处理 KVO 通知。通常来说,我们不推荐把 KVO 和多线程混起来。如果我们要用多个队列和线程,我们不应该在它们互相之间用 KVO。KVO 是同步运行的这个特性非常强大,只要我们在单一线程上面运行(比如主队列 main queue)
大量数据对一个属性观察,有什么问题 怎么实现一个埋点
常见的埋点有三种
页面进入次数
页面停留时间
点击事件
针对1、2两种埋点实现相对比较容易,我们可以使用runtime替换掉VC的viewWillAppear和viewWillDisappear两个系统方法来加入埋点代码。点击事件的埋点由于业务场景比较多,要实现无侵入埋点就比较难了。
思路:
我们可以使用runtime替换到点击事件sendAction:to:forEvent:,然后在替换方法里加入埋点代码。还是前面说的,点击事件场景比较多,要确定某个点击事件比较复杂。目前我们点击事件埋点还是在具体的某个点击事件里加入埋点代码。
识货
自己实现一个异常的捕获
- 系统Crash
对于系统Crash而引起的程序异常退出,可以通过UncaughtExceptionHandler机制捕获;也就是说在程序中catch以外的内容,被系统自带的错误处理而捕获。我们要做的就是用自定义的函数替代该ExceptionHandler即可。- 处理signal
使用Objective-C的异常处理是不能得到signal的,如果要处理它,我们还要利用unix标准的signal机制,注册SIGABRT, SIGBUS, SIGSEGV等信号发生时的处理函数。该函数中我们可以输出栈信息,版本信息等其他一切我们所想要的。
html怎么调用oc 底层怎么实现的
Swift中的RAC 不管是哪个vc怎么获取viewdidload方法
用方法交换
怎么让父类的initial方法不调用
如果分类和父类均实现了+initialize,则只有分类的+initialize会被调用;
如果父类和子类均实现了+initialize,第一次引用 子类时,先调用父类的+initialize,再调用子类的+initialize;
如果子类未实现initialize 方法,父类实现了+initialize,则第一次引用子类时,会调用两次父类的+initialize
数组下标越界
字典构造与修改
NSAttributedString相关
呈现一个空控制器
强引用一个单例对象
unrecognized selector
操作tableView数据
Push到同一个控制器多次
中通一面:
AFN的缓存 怎么存储的 AFNetworking的缓存机制
LRU缓存和 NSCache怎么存储的
NSCache主要用来存储临时数据(键值对),当内存资源不够时,系统会自动释放部分数据。它有三个特点:
• NSCache为了保持不占用过多的系统内存,它有多种自动回收内存策略;当系统内存出现不足时,它会回收部分内存使系统正常运转,这种回收是不可控的。
• 可以在多线程中对NSCache进行访问,同时不需要加锁,因为它是线程安全的。
• 与NSMutableDictionary不同,NSCache不会copy其内部的键对象。
由上边的特点看出,NSCache是一个很好的内存缓存类,通过它我们可以实现数据的缓存功能。常见的开源框架中也有NSCache的使用,AFN的图片缓存,SDWebImage等。
怎么去中断一个线程
coreData 中怎么创建主键
coreData 没有主键的概念
CoreData 多线程
读写文件时,读和写都不安全吗
京东
c语言 const 和 const
当在最前面的时候,表示指针不允许被改变,值可以改变.
const NSString * nameFir = @"test";
当在中间的时候,同上
NSString const * nameSec = @"test";
当在最后的时候,表示指针可以被改变,但是值不能改变(最常用)
NSString * const nameThi = @"test";
- 经验总结 const右边最近的内容不可以被改变.
c语言,结构体和共同体
bss段 https://www.jianshu.com/p/2d4acf4a53f9
内存分为5个区域,分别指的是----->栈区/堆区/BSS段/数据段/代码段 栈:存储局部变量,当其作用域执行完毕之后,就会被系统立即收回
堆:存储OC对象,手动申请的字节空间,需要调用free来释放
BSS段:未初始化的全局变量和静态变量,一旦初始化就会从BSS段中回收掉,转存到数据段中
数据段:存储已经初始化的全局变量和静态变量,以及常量数据,直到结束程序时才会被立即收回
常量区:存放常量字符串,程序结束后由系统释放
代码段:存放函数的二进制代码,直到结束程序时才会被立即收回
int和NSinteger有什么区别
NSInteger会自动识别当前电脑系统是32位还是64位数,然后自动返回最大的类型(int还是NSInteger)。例如,当前电脑为32位系统,你声明的NSInteger自动变为int。当前电脑为64位系统,你声明的NSInteger还是NSInteger。
所以32位系统,int的长度等于NSInteger的长度;64位系统,int的长度小于NSInteger的长度;也就是说NSInteger的长度一定是大于等于int的长度的。
知道了这个原理,当你不知道电脑的系统是几位,并且你正在声明一个整形变量,你一定要使用NSInteger,不要使用int,你可以当成一种规范。记住:在多数情况下一定尽可能的使用NSInteger。
重定向码是多少,放在那个字段里面 重定向,300-399,放在location字段
为什么4次挥手
oc调is
要先注册
二 我们在控制器中初始化WKWebView,注册方法.
1.初始化
//创建网页配置对象.
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
//是使用h5的视频播放器在线播放, 还是使用原生播放器全屏播放
configuration.allowsInlineMediaPlayback = YES;
//设置视频是否需要用户手动播放 设置为NO则会允许自动播放
if (@available(iOS 10.0, *)) {
configuration.mediaTypesRequiringUserActionForPlayback = YES;
} else {}
//设置是否允许画中画技术 在特定设备上有效
configuration.allowsPictureInPictureMediaPlayback = YES;
//设置请求的User-Agent信息中应用程序名称 iOS9后可用
configuration.applicationNameForUserAgent = @"ChinaDailyForiPad";
//自定义的WKScriptMessageHandler 是为了解决内存不释放的问题.
WeakWebViewScriptMessageDelegate *weakScriptMessageDelegate = [[WeakWebViewScriptMessageDelegate alloc] initWithDelegate:self];
//这个类主要用来做native与JavaScript的交互管理
WKUserContentController * wkUController = [[WKUserContentController alloc] init];
//注册一个name为jsToOcNoPrams的js方法 设置处理接收JS方法的对象
[wkUController addScriptMessageHandler:weakScriptMessageDelegate name:@"jsToOcNoPrams"];
[wkUController addScriptMessageHandler:weakScriptMessageDelegate name:@"jsToOcWithPrams"];
configuration.userContentController = wkUController;
//创建设置对象.
WKPreferences *preference = [[WKPreferences alloc]init];
//最小字体大小 当将javaScriptEnabled属性设置为NO时,可以看到明显的效果
preference.minimumFontSize = 0;
//设置是否支持javaScript 默认是支持的
preference.javaScriptEnabled = YES;
//在iOS上默认为NO,表示是否允许不经过用户交互由javaScript自动打开窗口
preference.javaScriptCanOpenWindowsAutomatically = YES;
configuration.preferences = preference;
self.webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height) configuration:configuration];
//UI代理.
self.webView.UIDelegate = self;
//导航代理.
self.webView.navigationDelegate = self;
//是否允许手势左滑返回上一级, 类似导航控制的左滑返回.
self.webView.allowsBackForwardNavigationGestures = YES;
(滑动显示更多)
autolayout 与frame区别
把frame设置写到layoutSubviews中或者写到viewDidLayoutSubviews中即可。因为约束生效时view的center或者bounds就会被修改,center或者bounds被修改时layoutSubview,就会被调用,随后viewDidLayoutSubviews就回被调用。这个时候,设置约束的视图frame就不再是(0,0,0,0)了
如果我们必须要将约束和frame写在同一方法中,写完约束就设置frame,而不是想把frame的设置写到layoutSubview中(比如我们设置好约束后马上就想根据约束的结果计算高度),那么我们还可以在设置完约束之后手动调用layoutIfNeeded方法,让视图立即layout,更新frame。在这之后就可以拿到设置约束的视图的尺寸了。
值类型属性包装器
怎么判断对钩手势
- assign修饰,释放不了,出现野指针
状态机
iOS开发笔记之七十三——基于状态机的页面构建方案_iOS开发笔记-CSDN博客_ios 状态机
关联库
设计一个app,架构上
点击H5会调原生的方法,原理是因为拦截
要先注册
https://mp.weixin.qq.com/s/iFEfgzU1g9RghFb9rpLHCg
left和leading 区别
在中国 ,left和leading是一样的,但是在阿拉伯,leading相当于right
三等分一个view
Swift
逃逸与非逃逸注意点
非逃逸闭包:闭包调用发生在函数结束前,闭包调用在函数作用域内
逃逸闭包:闭包调用有可能在函数结束后调用,闭包调用逃离了函数的作用域,需要@escaping声明
逃逸闭包不能捕获inout参数
MVVM
MVVM的作用就瘦身吗
二进制重拍
线程同步,使用锁
检测存在uiwebview 用逆向Grep
block获取的是地址值吗
block 捕获的是指针指向的内存地址 __blcok修饰可以捕获指针的地址
nsurlsession 和nsurlconnection 区别
设计一个malloc 和release
UIGraphicsBeginImageContextWithOptions(contentSize, NO, [UIScreen mainScreen].scale);
CGContextRef content = UIGraphicsGetCurrentContext();
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CFRelease(path);
copy自定义对象?如何拷贝大的数据量
使用归档
如果对象很多或者层级很多,实现起来还是很麻烦的。如果需要实现完全复制同样还有另有一种方法,那就是归档:
UI问题,tableciew有3个半,那一共有几个
copy很多数据
方法不让别人用,报错,怎么写代码
使用NS_DESIGNATED_INITIALIZER,NS_UNAVAILABLE将可以禁止系统方法的使用,所以如果你想禁止使用某个方法可以尽量用NS_DESIGNATED_INITIALIZER,NS_UNAVAILABLE来修饰方法
组件化,使用字典会有很多字符串(硬编码)
怎么优化,传递模型?
,Swift
Json转Model
面试
https://juejin.cn/post/7006273689675120677
lazy遇到的问题
https://juejin.cn/post/6844903571209584653
没故事的桌同学 Swift Collection 中的 lazy 作用
全局队列有2个枚举
竞争和非竞争
http 3次握手之前做什么
DNS 转ip
瀑布流
锁怎么工作的
Runloop 有几种不同状态,会退出吗
source0 // 处理触摸事件 例如:performSelector:onThread
Source1 // 基于Port 的线程间通信
Timers // NSTimer performSelector:withObject:afterDelay
Observers // 用于监听RunLoop的状态 UI 刷新 (BeforeWaiting) AutoRelease pool (BeforeWaiting)
Hook方法注入是动态库,那系统是如何调用我们的方法的
如何交换c语言的方法
检测FPS
交换oc方法,但是要自己写的方法和交换的方法都执行,怎么处理
imp和sel区别,和Select有什么区别
SEL:类成员方法的指针,与C的函数指针不一样,函数指针直接保存了方法的地址,而SEL只是方法的编号。
IMP是函数指针,指向方法的地址。方法名称不包括返回类型、参数类型,而又因为方法名相同对应的SEL相同,所以Objc不支持相同的方法名有不同的返回类型,也不支持重载,不过类方法和实例方法可以有相同的名字,而又有不同类型的参数和返回类型,因为它们不是处在同一张diapatch table中。
不仅类的方法可以在运行时创建,类本身也可以在运行时刻创建,只要类继承NSObject类。
OC如何实现多继承
- 通过组合的方式实现多继承
这种方式最简单粗暴,在子类中创建父类对象,外部调用时让父类对象去调用父类方法,从而实现多继承。- 通过协议实现多继承
因为OC允许一个类遵守多个协议,所以我们可以通过协议的方式模拟多继承。但是协议只能提供接口,不能提供实现,所以我们需要在子类中添加对应的实现,这也注定了协议实现多继承是不完美的。- 通过分类Category实现多继承
socket和http区别
HTTP协议:简单对象访问协议,对应于应用层 ,HTTP协议是基于TCP连接的
tcp协议: 对应于传输层
ip协议: 对应于网络层
TCP/IP是传输层协议,主要解决数据如何在网络中传输;而HTTP是应用层协议,主要解决如何包装数据。
Socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过Socket,才能使用TCP/IP协议。
http连接:http连接就是所谓的短连接,即客户端向服务器端发送一次请求,服务器端响应后连接即会断掉;
socket连接:socket连接就是所谓的长连接,理论上客户端和服务器端一旦建立起连接将不会主动断掉;但是由于各种环境因素可能会是连接断开,比如说:服务器端或客户端主机down了,网络故障,或者两者之间长时间没有数据传输,网络防火墙可能会断开该连接以释放网络资源。
mmap
熟悉fastlane的工具
Masonry有什么缺点,时间复杂度是多少
网络访问ip
目标ip和源ip会有变化吗
不会