开发进程中常用到哪些定时器,定时器时刻会有差错吗,假如有,为什么会有差错?
在iOS开发中,常用的定时器包括NSTimer
、CADisplayLink
和DispatchSourceTimer
。
-
NSTimer
:它是Foundation结构供给的一种定时器机制。能够经过指定时刻距离和目标目标来创立一个重复或单次触发的定时器。 -
CADisplayLink
:它是CoreAnimation结构供给的定时器,用于和屏幕的改写率同步。一般用于需求以屏幕改写频率进行精确更新的动画操作。 -
DispatchSourceTimer
:它是Grand Central Dispatch (GCD) 供给的一种定时器完成。能够创立一个高精度的定时器,能够在主队列或自定义队列上履行。
关于定时器时刻差错的问题,定时器的触发时刻或许会有必定的差错。这是由于多种要素导致的,包括体系负载、调度推延和定时器本身的完成机制等。
-
体系负载:假如体系负载较重,例如同时运转多个耗时使命,定时器触发或许会遭到推延。体系会优先处理其他使命,导致定时器触发时刻推延。
-
调度推延:定时器的触发需求经过体系的调度和处理。在这个进程中或许会存在一些推延,尤其是当体系忙碌时。这些推延会导致定时器的触发时刻与预期有必定的差错。
-
定时器完成机制:不同的定时器完成机制关于时刻的处理方法也不同,或许会引进必定的差错。例如,依据
NSTimer
的定时器在主线程运转时,或许会遭到主线程其他操作的影响,导致触发时刻不精确。
当涉及到定时器的时刻精度和差错时,以下是一些更详细的信息:
-
NSTimer
的时刻差错:NSTimer
是依据运转循环(run loop)的定时器,它的触发时刻或许会遭到运转循环形式、运转循环优先级、使命队列等要素的影响。在默许的运转循环形式下,NSTimer
的触发时刻或许会遭到其他使命(例如UI事情、网络恳求等)的影响,导致触发时刻有必定的差错。此外,假如在主线程上履行耗时操作,也会对NSTimer
的精确性发生影响。 -
CADisplayLink
的时刻精度:CADisplayLink
是与设备屏幕改写率同步的定时器,每次屏幕改写时触发。它的时刻精度一般是比较高的,由于它能够以每秒60次(60Hz)的频率触发。但是,即使是CADisplayLink
也或许遭到某些要素的影响而发生必定的差错,例如体系负载或其他耗时使命的履行。 -
DispatchSourceTimer
的时刻精度:DispatchSourceTimer
是依据Grand Central Dispatch (GCD) 的定时器,它供给了更高精度的定时器功用。能够经过指定leeway
参数来操控定时器的精度。leeway
值越小,定时器的触发时刻越挨近预期,但也或许增加体系负载。需求依据实践需求和功用要求来挑选适宜的leeway
值。
整体而言,定时器的时刻差错是难以完全防止的,尤其在杂乱的体系环境中。运用程序的功用、体系负载、其他使命和操作等都会对定时器的精确性发生影响。在开发进程中,能够采纳以下办法来处理定时器差错:
-
运用适宜的定时器类型:依据需求挑选适宜的定时器类型,例如需求高精度的定时器能够挑选
CADisplayLink
或DispatchSourceTimer
。 -
考虑时刻忍受规模:关于某些运用场景,或许能够忍受必定的时刻差错。在规划定时器相关的逻辑时,能够依据实践需求和状况,设置一个合理的时刻忍受规模。
-
防止在主线程上履行耗时操作:将耗时操作放在后台线程上履行,能够减小主线程的负载,进步定时器的精确性。
-
测验和优化:在开发进程中,能够进行测验和优化,经过监测定时器的触发时刻和功用表现,逐渐优化代码,减小差错。
代码示例:
- 运用
NSTimer
:
// 创立一个重复触发的NSTimer
let timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { timer in
// 定时器触发时履行的代码
print("NSTimer triggered!")
}
// 中止定时器
timer.invalidate()
- 运用
CADisplayLink
:
// 创立一个CADisplayLink
let displayLink = CADisplayLink(target: self, selector: #selector(update))
// 设置显示屏改写时触发的办法
@objc private func update(_ displayLink: CADisplayLink) {
// 定时器触发时履行的代码
print("CADisplayLink triggered!")
}
// 将CADisplayLink增加到运转循环中
displayLink.add(to: .main, forMode: .default)
// 中止定时器
displayLink.invalidate()
- 运用
DispatchSourceTimer
:
// 创立一个DispatchSourceTimer
let timer = DispatchSource.makeTimerSource()
// 设置时刻距离和队列
let interval = DispatchTimeInterval.seconds(1)
let queue = DispatchQueue.global()
// 设置定时器触发时履行的代码
timer.setEventHandler {
print("DispatchSourceTimer triggered!")
}
// 发动定时器
timer.schedule(deadline: .now(), repeating: interval, leeway: .never)
timer.resume()
// 中止定时器
timer.cancel()
这些代码示例展示了在不同的定时器完成中怎么创立定时器、设置触发时刻和履行的代码,以及怎么中止定时器。
NSTimer、CADisplayLink会发生循环引证吗?假如会,你是怎么处理的?
假如直接运用,会发生循环引证问题。能够增加一个中间类,给这个类增加一个用weak润饰的id 类型target特点,并重写中间类的音讯转发办法。完成如下代码:
声明文件.h:
#import <Foundation/Foundation.h>
@interface LXProxy : NSProxy
+ (instancetype)proxyWithTarget:(id)target;
@end
仿制
完成文件.m
#import "LXProxy.h"
@interface LXProxy ()
/** weak target*/
@property (nonatomic, weak) id target;
@end
@implementation LXProxy
+ (instancetype)proxyWithTarget:(id)target{
LXProxy *proxy = [LXProxy alloc];
proxy.target = target;
return proxy;
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel{
return [self.target methodSignatureForSelector:sel];
}
- (void)forwardInvocation:(NSInvocation *)invocation{
[invocation invokeWithTarget:self.target];
}
@end
调用代码:
_timer = [NSTimer scheduledTimerWithTimeInterval:2 target:[LXProxy proxyWithTarget:self] selector:@selector(test) userInfo:nil repeats:YES];
UIView和CALayer有了解吗,UI卡顿原因是什么?
UIView是用户界面中的可视化元素,它负责处理视图的布局、制作和事情处理等使命。每个UIView目标都有相关的CALayer目标,CALayer负责实践的制作和动画。
CALayer是Core Animation结构的一部分,它是一种轻量级的目标,用于管理视图层次结构中的可视内容。CALayer负责处理视图的烘托、动画和变换等使命,它供给了一些特点和办法来操控视图的外观和行为。
UI卡顿是指用户界面的呼应性下降,导致界面动画不流通,用户交互的呼应推延等。UI卡顿的原因能够有多种,以下是一些或许的原因:
-
杂乱的视图层次结构:假如视图层次结构非常杂乱,视图嵌套层级过深,会增加烘托和布局的工作量,导致功用下降。
-
频频的布局核算:当视图的布局需求频频核算时,比方在翻滚视图中,主动布局体系需求不断从头核算和调整视图的方位和巨细,这或许会导致功用问题。
-
制作进程中的耗时操作:假如视图的制作进程中包括杂乱的制作操作或许频频的重绘,会增加CPU的负载,导致界面卡顿。
-
频频的视图更新和动画:假如视图频频地进行更新和动画操作,比方改动视图的方位、巨细、透明度等特点,会导致界面卡顿。
-
主线程堵塞:假如在主线程上履行了耗时的操作,比方网络恳求、很多数据的处理等,会堵塞主线程的运转,导致界面无法及时呼运用户的操作。
为了处理UI卡顿问题,能够采纳以下办法:
-
异步制作和布局:为了防止在主线程上履行耗时的制作和布局操作,能够运用异步制作和布局机制。在iOS中,能够运用异步制作的技能,如
drawRect()
办法中的draw(in:)
办法、CALayerDelegate
的异步制作办法等,将制作操作放在后台线程进行。相同,能够运用主动布局引擎的异步布局功用,如UIView
的layoutIfNeeded()
办法在异步线程上履行布局核算。这样能够减轻主线程的负担,进步界面的呼应性。 -
削减视图重绘:视图的重绘是一项开销较大的操作,特别是在频频更新视图特点或进行杂乱制作时。为了削减重绘,能够运用以下办法:
- 防止频频调用
setNeedsDisplay()
或setNeedsLayout()
办法,尽量兼并多个更新操作。 - 运用
CALayer
的shouldRasterize
特点将视图的内容缓存为位图,削减重绘次数。 - 运用
CAShapeLayer
替代CALayer
进行杂乱的制作,由于CAShapeLayer
采用矢量制作,功用更高。 - 关于静态内容,能够运用预烘托技能,将内容制作到位图上,并将位图作为视图的布景。
- 防止频频调用
-
合理运用动画:动画作用能够增加界面的交互性和吸引力,但过多或杂乱的动画会增加CPU和GPU的负载,导致卡顿。为了防止这种状况,能够考虑以下主张:
- 运用硬件加速的Core Animation动画,如依据
CALayer
的特点动画,而不是逐帧动画。 - 防止在很多视图上同时运用杂乱的动画作用。
- 关于杂乱的过渡动画,能够运用依据
CATransition
的动画作用,而不是手动更新视图特点。
- 运用硬件加速的Core Animation动画,如依据
-
主线程优化:主线程是处理UI事情和界面更新的关键线程,假如主线程被堵塞,会导致界面卡顿。为了优化主线程的功用,能够考虑以下办法:
- 将耗时的操作(如网络恳求、文件读写、图像处理等)放在后台线程履行,防止堵塞主线程。
- 运用多线程编程技能,如GCD(Grand Central Dispatch)或Operation Queue,将不同类型的使命分发到适宜的线程履行。
- 防止在主线程上进行很多的核算或数据处理操作,能够将这些操作分批处理,或许运用推延履行的方法,以削减对主线程的影响。
-
运用功用剖析东西:为了更好地了解和处理UI卡顿问题,能够运用功用剖析东西来监测运用程序的功用瓶颈。例如,在iOS开发中,能够运用Instruments东西中的Time Profiler、CPU Profiler、Core Animation等东西来识别功用瓶颈,并找出导致卡顿的详细原因。经过剖析功用数据,能够有针对性地进行优化和改善。
需求注意的是,UI卡顿问题或许与详细的运用程序和环境有关,因而处理方案或许因状况而异。在开发进程中,主张综合考虑,并依据详细状况进行优化和改善,以进步运用程序的功用和用户体验。
对Runtime有了解吗,Runtime的办法查找进程是什么样的?有哪些实践运用?
在iOS开发中,Objective-C Runtime是一个运转时体系,它供给了一组API来支撑Objective-C语言的动态特性。它答应开发人员在运转时经过代码操作类、目标和办法,而不仅仅是在编译时。
在Runtime中,办法查找是经过音讯传递机制来完成的。当调用一个办法时,Runtime会依据办法的挑选器(Selector)在类的办法列表中查找对应的完成。假如找到了匹配的办法,就会履行该办法;假如没有找到,Runtime会经过一系列的查找和调用机制,测验找到适宜的办法完成或履行默许的处理方法。
办法查找的进程大致如下:
-
首要,Runtime会在目标所属的类的办法列表中查找与挑选器相匹配的办法完成。假如找到了匹配的办法,就会履行该办法。
-
假如在类的办法列表中没有找到匹配的办法完成,Runtime会沿着类的承继链向上查找,直到找到匹配的办法完成或到达根类(如NSObject)停止。
-
假如在类及其父类的办法列表中都没有找到匹配的办法完成,Runtime会调用
+resolveInstanceMethod:
或+resolveClassMethod:
办法,给开发者一个动态增加办法的时机。 -
假如开发者在
+resolveInstanceMethod:
或+resolveClassMethod:
办法中未增加办法完成,Runtime会持续履行音讯转发流程。 -
音讯转发分为两个阶段:首要,Runtime会调用
-forwardingTargetForSelector:
办法,答应开发者指定一个目标来接收该音讯。假如返回了一个非nil的目标,Runtime会将音讯转发给该目标,让其处理。其次,假如上一步没有成功,Runtime会调用-methodSignatureForSelector:
办法获取办法的签名,然后调用-forwardInvocation:
办法将音讯封装成NSInvocation目标,并将其传递给其他目标处理。 -
假如以上进程仍未找到能够处理音讯的目标,Runtime会触发不知道办法处理机制,经过
-doesNotRecognizeSelector:
办法抛出反常或履行其他自定义的操作。
Objective-C Runtime的办法查找进程答应开发人员在运转时为目标动态增加办法、交流办法完成、替换办法完成等,然后完成一些高档的编程技巧和功用。
一些实践运用包括:
-
动态办法解析:经过Runtime的办法查找进程,能够在运转时动态增加办法,完成一些动态特性和行为。
-
办法交流:运用Runtime的办法查找和交流机制,能够交流类中的两个办法的完成,完成办法的替换和增强。
-
音讯转发:经过Runtime的音讯转发机制,能够将无法处理的音讯转发给其他目标,完成灵活的音讯处理和分发。
-
相关目标:运用Runtime的相关目标机制,能够在运转时为现有的类增加相关特点,扩展其功用。
-
动态创立类和目标:Runtime供给了创立和操作类和目标的API,能够在运转时动态创立类和目标,完成类似于动态署理等功用。
以下是更多信息和相关概念:
-
类与目标的运转时表明:在Objective-C Runtime中,类和目标都有对应的运转时表明。每个类在运转时都有一个与之相关的
Class
目标,用于描述类的信息,包括办法列表、特点、实例变量等。而每个目标在运转时都有一个与之相关的isa
指针,指向其所属的类。 -
办法的运转时表明:Objective-C中的办法在运转时由
Method
结构体表明,包括办法的挑选器(Selector)和办法的完成(IMP)。挑选器是办法名的仅有标识符,而IMP是指向办法完成代码的函数指针。 -
办法交流(Method Swizzling):Runtime答应开发者在运转时交流类中的两个办法的完成。这一技能常用于在不修正源代码的状况下修正类的行为,完成办法的替换和增强。但需求慎重运用,防止引进混乱和杂乱性。
-
相关目标(Associated Objects):Runtime供给了相关目标的机制,答应开发者为现有的类增加相关特点。经过这个机制,能够在运转时为目标动态增加特点,而无需修正类的声明或承继联系。
-
动态办法解析(Dynamic Method Resolution):当Runtime在办法查找进程中找不到匹配的办法完成时,会触发动态办法解析机制。开发者能够经过完成
+resolveInstanceMethod:
或+resolveClassMethod:
办法,在运转时动态增加办法的完成。 -
音讯转发(Message Forwarding):当Runtime在动态办法解析后依然找不到办法完成时,会触发音讯转发机制。开发者能够经过完成
-forwardingTargetForSelector:
、-methodSignatureForSelector:
和-forwardInvocation:
等办法,将音讯转发给其他目标处理。这为完成署理、音讯转发链和音讯转发中间件等供给了灵活的机制。 -
类的动态创立与修正:Objective-C Runtime答应在运转时动态创立类和目标,以及修正已有类的特点、办法等。这为一些特别需求和高档编程技巧供给了支撑,如动态署理、动态子类化等。
-
运用Runtime进行调试和探索:Runtime供给了一些调试和探索东西和函数,能够用于动态检查类的信息、办法调用流程、动态调试等。这些东西和函数关于理解和剖析Objective-C运转时行为很有帮助。
Objective-C Runtime为开发者供给了强壮的动态编程能力,使得在运转时修正类和目标的行为成为或许。但是,运用Runtime时需求小心慎重,保证正确运用和遵从规范,以防止引进难以调试和保护的代码。
HTTPS和HTTP有什么差异,HTTPS加密进程是什么样的,对称加密和非对称解密各有什么优缺陷?
HTTPS(Hypertext Transfer Protocol Secure)是一种安全的通讯协议,用于在网络上传输加密的数据。与HTTP比较,HTTPS经过运用加密技能来供给更高的数据传输安全性。
差异:
-
安全性:HTTP是明文传输协议,数据在网络上传输时不加密,容易被偷听和篡改。而HTTPS运用SSL(Secure Socket Layer)或TLS(Transport Layer Security)协议对通讯进行加密,保证数据在传输进程中的机密性和完整性。
-
加密方法:HTTP不供给任何加密机制,而HTTPS运用加密技能来保护数据。HTTPS运用对称加密和非对称加密相结合的方法,保证数据的保密性和安全性。
HTTPS加密进程:
-
客户端发送HTTPS恳求到服务器,并恳求树立安全衔接。
-
服务器将自己的公钥发送给客户端。
-
客户端验证服务器的证书有效性,并生成一串随机的对称加密密钥(Session Key)。
-
客户端运用服务器的公钥对Session Key进行加密,并发送给服务器。
-
服务器运用私钥解密客户端发送的加密的Session Key。
-
客户端和服务器都获得了相同的Session Key,之后的通讯将运用对称加密算法(如AES)来加密和解密数据。
-
客户端和服务器之间的通讯运用Session Key进行加密和解密,保证数据的机密性和完整性。
对称加密和非对称加密的优缺陷:
对称加密:
- 长处:对称加密算法核算速度快,加密解密功率高,合适很多数据的加密和解密操作。
- 缺陷:对称加密算法运用相同的密钥进行加密和解密,密钥需求在通讯两边之间共享,容易被截获和破解。
非对称加密:
- 长处:非对称加密运用公钥加密、私钥解密,安全性较高,密钥对中的私钥保密性要求较高,不易被破解。
- 缺陷:非对称加密算法核算速度相对较慢,密钥长度较长,占用较大的存储空间,不合适对很多数据进行加密和解密操作。
为了兼顾对称加密和非对称加密的长处,HTTPS运用非对称加密算法(如RSA)来安全地交流对称加密算法所需的密钥,然后运用对称加密算法来加密实践的数据传输,然后保证了安全性和功率的平衡。
TCP和UDP有什么差异,TCP是牢靠传输吗,怎么保证其牢靠性?
TCP(传输操控协议)和UDP(用户数据报协议)是互联网协议族中的两个首要传输层协议。它们有以下差异:
-
衔接导向 vs. 无衔接:TCP是一种衔接导向的协议,它在通讯两边树立衔接之后进行牢靠的数据传输。UDP是一种无衔接的协议,通讯两边之间没有先树立衔接,直接进行数据传输。
-
牢靠性 vs. 速度:TCP供给牢靠的数据传输,保证数据依照发送顺序到达目的地,并进行过错检测和重传机制。UDP则愈加重视传输速度,不供给数据牢靠性和重传机制,因而速度更快,但数据或许会丢失、重复或乱序。
-
流式传输 vs. 数据报传输:TCP供给面向流的传输,它将数据视为接连的字节省。UDP则是一种数据报传输协议,它将数据划分为较小的数据报进行传输。
关于TCP的牢靠性,TCP经过以下机制来保证数据传输的牢靠性:
-
序列号和承认应对:每个TCP报文段都包括一个序列号,用于标识报文段在数据流中的方位。接收方会发送承认应对,奉告发送方已经成功接收到数据。
-
数据重传:假如发送方没有收到承认应对,会进行定时重传,保证数据牢靠传输。
-
滑动窗口:TCP运用滑动窗口机制来操控发送方和接收方之间的数据流量。它答应发送方接连发送多个报文段,而不需求等待承认应对,然后进步传输功率。
-
拥塞操控:TCP具有拥塞操控机制,它经过动态调整发送速率来防止网络拥塞。当网络拥塞时,TCP会削减发送速率,保证网络的稳定性。
这些机制使得TCP能够在不牢靠的网络环境中供给牢靠的数据传输。但是,这也导致TCP的传输功率相对较低,尤其在高推延或丢包较多的网络环境中。因而,依据运用程序的需求,挑选合适的协议(TCP或UDP)非常重要。 例如,在高推延或丢包较多的网络环境中,TCP的重传机制或许会导致较长的传输推延。此外,TCP的衔接树立和保护进程也需求必定的时刻和资源。因而,关于某些特定的运用场景,如实时游戏和实时通讯运用,UDP或许更适宜,由于它更重视传输速度和实时性。在挑选协议时,需求考虑运用程序的需求和网络环境的特点。