block
的内部完成,结构体是什么样的
在Objective-C中,block是一种闭包,它能够封装一段代码以及其履行环境。当咱们定义一个block时,它在编译后的底层存储结构是一个结构体。
下面是block的底层结构体示例:
struct __block_impl {
void *isa;
int Flags;
int Reserved;
void *FuncPtr;
};
struct __main_block_impl_0 {
struct __block_impl impl;
struct __main_block_desc_0* Desc;
int age;
};
-
__block_impl
结构体是一切block结构体的基础,它包含了一些通用的字段,如isa
指针、标志位和保留字段。 -
__main_block_impl_0
结构体是详细的block结构体,它承继自__block_impl
结构体,并包含了block的描述信息和捕获的外部变量。
在上面的示例中,__main_block_impl_0
结构体中有一个age
字段,表明捕获的外部变量。当咱们调用block时,实际上是经过FuncPtr
函数指针找到封装的函数并将block的地址作为参数传给这个函数进行履行。在函数履行过程中,能够经过结构体中的字段拜访捕获的外部变量。
需求留意的是,block的底层结构体可能会依据详细的状况而有所不同,上述示例只是一个简略的示意。详细的结构体定义可能会依据编译器和代码的不同而有所改变。
Learn more:
iOS开发中有多少类型的线程?别离比照
在iOS开发中,常见的线程类型有以下几种:
-
主线程(Main Thread):也称为UI线程,用于处理用户界面的更新和事件呼应。一切UI相关的操作都必须在主线程上履行,否则会导致界面卡顿或溃散。
-
后台线程(Background Thread):用于履行耗时的使命,不会阻塞主线程。能够运用GCD(Grand Central Dispatch)或NSOperationQueue来创立和办理后台线程。
-
大局并发行列(Global Concurrent Queue):是GCD供给的一种并发行列,能够一起履行多个使命。大局并发行列是体系供给的,不需求手动创立,能够经过
dispatch_get_global_queue
函数获取。 -
自定义并发行列(Custom Concurrent Queue):能够运用GCD创立自定义的并发行列,用于履行多个使命。自定义并发行列能够经过
dispatch_queue_create
函数创立。 -
串行行列(Serial Queue):是一种特殊的自定义行列,用于按次序履行使命,每次只能履行一个使命。串行行列能够经过
dispatch_queue_create
函数创立。 -
主行列(Main Queue):是一种特殊的串行行列,用于在主线程上履行使命。主行列是体系供给的,不需求手动创立,能够经过
dispatch_get_main_queue
函数获取。 -
主行列和大局并发行列的比较:
- 主行列只在主线程上履行使命,适用于更新UI和处理用户事件等操作。
- 大局并发行列能够在后台线程上履行使命,适用于履行耗时操作和并发履行多个使命。
-
线程安全性:
- 主行列和主线程是线程安全的,能够直接在主行列或主线程上履行使命。
- 大局并发行列和后台线程对错线程安全的,需求运用锁或其他同步机制来保证数据的安全拜访。
综上所述,iOS开发中常见的线程类型包含主线程、后台线程、大局并发行列、自定义并发行列、串行行列和主行列。不同的线程类型适用于不同的场景,需求依据详细需求挑选合适的线程类型来履行使命。
-
NSThread,每个 NSThread目标对应一个线程,量级较轻,一般咱们会起一个 runloop 保活,然后经过增加自定义source0源或许 perform onThread 来进行调用,长处轻量级,运用简略,缺陷:需求自己办理线程的生命周期,保活,另外还会线程同步,加锁、睡觉和唤醒。
-
GCD:Grand Central Dispatch(派发) 是基于C言语的结构,能够充分利用多核,是苹果推荐运用的多线程技能
- 长处:GCD更接近底层,而NSOperationQueue则更高级笼统,所以GCD在寻求功能的底层操作来说,是速度最快的,有待确认
- 缺陷:操作之间的事务性,次序行,依赖联系。GCD需求自己写更多的代码来完成
-
NSOperation
-
长处: 运用者的关注点都放在了 operation 上,而不需求线程办理。
- 支撑在操作目标之间依赖联系,方便操控履行次序。
- 支撑可选的完成块,它在操作的主要使命完成后履行。
- 支撑运用KVO告诉监视操作履行状态的改变。
- 支撑设定操作的优先级,从而影响它们的相对履行次序。
- 支撑取消操作,答应您在操作履行时暂停操作。
-
缺陷:高级笼统,功能方面相较 GCD 来说缺乏一些;
-
Learn more:
GCD有哪些行列,默许供给哪些行列
GCD(Grand Central Dispatch)是一套用于多线程编程的低层API,它供给了一种方便的办法来办理并发使命。在GCD中,有多品种型的行列可供运用,包含默许供给的行列。
以下是GCD中常用的行列类型和默许供给的行列:
-
主行列(Main Queue):主行列是一个串行行列,用于在主线程上履行使命。它是由体系主动创立的,能够经过调用
dispatch_get_main_queue()
来获取主行列的引证。 -
大局并发行列(Global Concurrent Queue):大局并发行列是一个并行行列,用于在后台线程上履行使命。它供给了多个优先级,能够依据使命的重要性挑选不同的优先级。能够经过调用
dispatch_get_global_queue()
来获取大局并发行列的引证。 -
自定义行列(Custom Queue):除了主行列和大局并发行列,还能够创立自定义行列。自定义行列能够是串行行列(Serial Queue)或并行行列(Concurrent Queue)。串行行列按照使命的提交次序依次履行,而并行行列能够一起履行多个使命。能够经过调用
dispatch_queue_create()
来创立自定义行列。
总结起来,GCD供给了三种常用的行列类型:主行列、大局并发行列和自定义行列。主行列用于在主线程上履行使命,大局并发行列用于在后台线程上履行使命,而自定义行列能够依据需求挑选串行或并行履行使命。
Learn more:
GCD有哪些办法api
GCD(Grand Central Dispatch)是iOS开发中常用的多线程编程技能之一,它供给了一系列的API来办理和调度使命的履行。下面是一些常用的GCD办法API:
-
创立Dispatch Queue:
-
dispatch_queue_create
:创立一个自定义的Dispatch Queue [2].
-
-
获取体系供给的Dispatch Queue:
-
向Dispatch Queue中追加使命:
-
延迟履行使命:
-
dispatch_after
:在指定的时间后履行使命 [2].
-
-
Dispatch Group:
-
Dispatch Barrier:
-
dispatch_barrier_async
:将指定的使命追加到Concurrent Dispatch Queue中,并在该使命履行完毕后再持续履行其他使命 [3].
-
这些是GCD中常用的办法API,经过它们能够完成多线程编程和使命调度。更多关于GCD的详细运用办法和阐明,能够参考相关的文档和教程。
Learn more:
如何完成同步,有多少办法就说多少
在iOS中,完成同步的办法有多种。下面是一些常用的同步办法:
-
运用GCD(Grand Central Dispatch):
- 运用
dispatch_sync
函数将使命同步提交到指定的行列中,等候使命履行完成后再持续履行后续代码。 - 运用
dispatch_barrier_sync
函数将使命同步提交到自定义的并行行列中,等候使命履行完成后再持续履行后续代码。 - 运用
dispatch_group_wait
函数等候指定的使命组中的使命履行完成后再持续履行后续代码。
- 运用
-
运用NSOperation和NSOperationQueue:
- 将使命封装成NSOperation目标,然后将NSOperation目标增加到NSOperationQueue中。
- 设置NSOperationQueue的
maxConcurrentOperationCount
属性为1,使使命串行履行。
-
运用锁:
- 运用OSSpinLock、os_unfair_lock、pthread_mutex等互斥锁来保证多线程拜访共享资源的同步性。
- 运用NSLock、NSRecursiveLock、NSCondition等目标来完成线程同步。
-
运用信号量:
- 运用dispatch_semaphore_create函数创立一个信号量,运用dispatch_semaphore_wait函数等候信号量,运用dispatch_semaphore_signal函数发送信号量。
-
运用dispatch_once函数:
- 运用dispatch_once函数能够保证某个代码块只会被履行一次,常用于单例形式的完成。
这些是iOS中常用的同步办法,依据详细的需求和场景挑选合适的办法来完成同步操作。
Learn more:
有哪些类型的线程锁,别离介绍下效果和运用场景
iOS中常用的线程锁类型包含:
-
OSSpinLock(自旋锁)
- 效果:用于维护临界区,保证只要一个线程能够拜访共享资源。
- 运用场景:适用于临界区履行时间短且线程竞赛不剧烈的状况。留意,OSSpinLock在iOS10之后现已不再线程安全[1]。
-
os_unfair_lock(互斥锁)
- 效果:用于维护临界区,保证只要一个线程能够拜访共享资源。
- 运用场景:适用于临界区履行时间长或线程竞赛剧烈的状况。os_unfair_lock是一种高功能的互斥锁,替代了OSSpinLock[1]。
-
dispatch_semaphore(信号量)
- 效果:用于操控一起拜访共享资源的线程数量。
- 运用场景:适用于需求约束并发线程数量的状况,比方操控并发网络请求的数量[1]。
-
pthread_mutex(互斥锁)
- 效果:用于维护临界区,保证只要一个线程能够拜访共享资源。
- 运用场景:适用于临界区履行时间长或线程竞赛剧烈的状况。pthread_mutex是一种标准的互斥锁,能够经过不同的属性设置来满足不同的需求[1]。
-
NSLock(互斥锁)
- 效果:用于维护临界区,保证只要一个线程能够拜访共享资源。
- 运用场景:适用于临界区履行时间长或线程竞赛剧烈的状况。NSLock是Foundation结构供给的一种简略的互斥锁[1]。
-
NSCondition(条件锁)
- 效果:用于线程之间的等候和唤醒。
- 运用场景:适用于需求线程间通讯的状况,能够经过条件变量来完成线程的等候和唤醒操作[1]。
-
NSRecursiveLock(递归锁)
- 效果:答应同一线程屡次加锁,防止死锁。
- 运用场景:适用于同一线程需求屡次加锁的状况,比方递归操作或循环中的加锁操作[1]。
-
@synchronized(递归锁)
- 效果:答应同一线程屡次加锁,防止死锁。
- 运用场景:适用于同一线程需求屡次加锁的状况,比方递归操作或循环中的加锁操作。@synchronized是Objective-C言语供给的一种简略的递归锁机制[1]。
-
pthread_mutex(recursive)(递归锁)
- 效果:答应同一线程屡次加锁,防止死锁。
- 运用场景:适用于同一线程需求屡次加锁的状况,比方递归操作或循环中的加锁操作。pthread_mutex(recursive)是pthread库供给的一种递归锁机制[1]。
Learn more:
NSTimer、CADisplayLink、dispatch_source_t 的优劣
NSTimer, CADisplayLink, and dispatch_source_t are three different timers available in iOS, each with its own advantages and disadvantages. Let’s compare them:
NSTimer:
- Advantages:
- Easy to use and widely used in iOS development.
- Can be scheduled on the main run loop with a specified time interval.
- Disadvantages:
- Limited precision, as it relies on the run loop and may be affected by other activities on the main thread [1].
- May not be suitable for real-time or high-precision timing requirements.
CADisplayLink:
- Advantages:
- Synchronized with the display refresh rate, typically 60 frames per second.
- Provides smooth animations and updates.
- Disadvantages:
- Limited to the refresh rate of the display, which may not be suitable for all timing requirements.
- Can only be used for UI-related tasks and not for general-purpose timing.
dispatch_source_t:
- Advantages:
- Provides high-precision timing and is suitable for real-time tasks.
- Can be used for both UI and non-UI related tasks.
- Offers various dispatch sources, including timers, signals, file descriptors, and more.
- Disadvantages:
- Requires a good understanding of Grand Central Dispatch (GCD) and its concepts.
- More complex to set up compared to NSTimer and CADisplayLink.
In summary, the choice of timer depends on the specific requirements of your application. If you need high precision and real-time timing, dispatch_source_t is a good option. If you are working with UI-related tasks and smooth animations, CADisplayLink is suitable. NSTimer is a simpler option but may not provide the same level of precision as the other two timers.
Learn more: