iOS核心系统编程最佳实践:线程

基于手机APP与蓝牙BLE的STM32低功耗遥控系统设计与实现 本文详细阐述了基于手机APP与蓝牙BLE的STM32低功耗遥控系统的设计与实现。系统通过手机APP发送指令,协调STM32与蓝牙模块协同进入深度待机模式,实现微安级待机功耗,并利用蓝牙模块的状态引脚可靠唤醒STM32,从而大幅延长电池供电设备的续航时间。 阅读详情


一、线程的创建:

操作对象(Operation objectis)可能创建线程更快,参阅:iOS核心系统编程最佳实践:并发

1、线程创建需要的内存和时间消耗都比较大,因此建议你的入口点函数做相当数量的工作,或建立一个Run Loops允许进行经常性的工作。

2、Run Loops可以让你使用最小的资源来创建长时间运行线程。因为run loop在没有任何事件处理的时候会把它的线程置于休眠状态,它消除了消耗CPU周期轮询,并防止处理器本身进入休眠状态并节省电源。

3、为了配置run loop,你所需要做的是启动你的线程,获取run loop的对象引用,设置你的事件处理程序,并告诉run loop运行。Cocoa和Carbon提供的基础设施会自动为你的主线程配置相应的run loop。如果你打算创建长时间运行的辅助线程,那么你必须为你的线程配置相应的run loop。

4、每一个线程都有其对应的RunLoop,但是默认非主线程的RunLoop是没有运行的,需要为RunLoop添加至少一个事件源,然后去run它。一般情况下我们是没有必要去启用线程的RunLoop的,除非你在一个单独的线程中需要长久的检测某个事件。

5、RunLoop,就是一个循环,只是这个循环里加入很多特性。 首先循环体的开始需要检测是否有需要处理的事件,如果有则去处理,如果没有则进入睡眠以节省CPU时间。所以重点便是这个需要处理的事件,在RunLoop中,需要处理的事件分两类,一种是输入源,一种是定时器,定时器好理解就是那些需要定时执行的操作,输入源分三类:performSelector源,基于端口(Mach port)的源,以及自定义的源。编程的时候可以添加自己的源。RunLoop还有一个观察者Observer的概念,可以往RunLoop中加入自己的观察者以便监控着RunLoop的运行过程,CFRunLoop.h中定义了所有观察者的类型:

enum CFRunLoopActivity {
   kCFRunLoopEntry = (1 << 0),
   kCFRunLoopBeforeTimers = (1 << 1),
   kCFRunLoopBeforeSources = (1 << 2),
   kCFRunLoopBeforeWaiting = (1 << 5),
   kCFRunLoopAfterWaiting = (1 << 6),
   kCFRunLoopExit = (1 << 7),
   kCFRunLoopAllActivities = 0x0FFFFFFFU
};
typedef enum CFRunLoopActivity CFRunLoopActivity;

如果你使用过select系统调用写过程序你便可以快速的理解runloop事件源的概念,本质上讲事件源的机制和select一样是一种多路复用IO的实现,在一个线程中我们需要做的事情并不单一,如需要处理定时钟事件,需要处理用户的触控事件,需要接受网络远端发过来的数据,将这些需要做的事情统统注册到事件源中,每一次循环的开始便去检查这些事件源是否有需要处理的数据,有的话则去处理。拿具体的应用举个例子,NSURLConnection网络数据请求,默认是异步的方式,其实现原理就是创建之后将其作为事件源加入到当前的RunLoop,而等待网络响应以及网络数据接受的过程则在一个新创建的独立的线程中完成,当这个线程处理到某个阶段的时候比如得到对方的响应或者接受完了网络数据之后便通知之前的线程去执行其相关的delegate方法。所以在Cocoa中经常看到<CODE>scheduleInRunLoop:forMode:</CODE>这样的方法,这个便是将其加入到事件源中,当检测到某个事件发生的时候,相关的delegate方法便被调用。对于CoreFoundation这一层而言,通常的模式是创建输入源,然后将输入源通过<CODE>CFRunLoopAddSource</CODE>函数加入到RunLoop中,相关事件发生后,相关的回调函数会被调用。如CFSocket的使用。另外RunLoop中还有一个运行模式的概念,每一个运行循环必然运行在某个模式下,而模式的存在是为了过滤事件源和观察者的,只有那些和当前RunLoop运行模式一致的事件源和观察者才会被激活。  

二、线程的启动:线程启动之后,线程就进入三个状态中的任何一个:运行(running)、就绪(ready)、阻塞(blocked)。如果一个线程当前没有运行,那么它不是处于阻塞,就是等待外部输入,或者已经准备就绪等待分配CPU。线程持续在这三个状态之间切换,直到它最终退出或者进入中断状态。

三、线程的执行:

1、线程同步:

NSLock:锁提供了一次只有一个线程可以执行代码的有效保护形式。最普遍的一种锁是互斥排他锁,也就是我们通常所说的“mutex”。当一个线程试图获取一个当前已经被其他线程占据的互斥锁的时候,它就会被阻塞直到其他线程释放该互斥锁。

NSCondition:条件确保在你的应用程序任务执行的适当顺序。一个条件作为一个看门人,阻塞给定的线程,直到它代表的条件变为真。当发生这种情况的时候,条件释放该线程并允许它继续执行。

原子操作也是另外一种保护和同步访问数据的方法。原子操作在以下情况的时候提供了替代锁的轻量级的方法,其中你可以执行标量数据类型的数学或逻辑运算。原子操作使用特殊的硬件设施来保证变量的改变在其他线程可以访问之前完成。

四、线程通信:Cocoa为iOS线程间通信提供2种方式,

一种是performSelector(多参数扩展http://bj007.blog.51cto.com/1701577/538995) 

@interface NSObject (NSThreadPerformAdditions)

- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray *)array;
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
// equivalent to the first method with kCFRunLoopCommonModes

- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray *)array NS_AVAILABLE(10_5, 2_0);
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait NS_AVAILABLE(10_5, 2_0);
// equivalent to the first method with kCFRunLoopCommonModes
    ...
@end

另一种是NSMachPort(NSMachPort是个鸡肋,线程间通信应该都通过performSelector来搞定)

 五、线程的退出

可以通过使用applicationShouldTerminate:的委托方法来延迟程序的中断直到一段时间后或者完成取消。当延迟中断的时候,你的程序需要等待直到任何周期线程已经完成它们的任务且调用了replyToApplicationShouldTerminate:方法。关于更多这些方法的信息,请查阅NSApplication Class Reference。

六、处理异常

1、Cocoa里面,一个NSException对象是一个自包含对象,一旦它被引发了,那么它可以从一个线程传递到另外一个线程。

2、在一些情况下,异常处理可能是自动创建的。比如,Objective-C中的@synchronized包含了一个隐式的异常处理。

3、如果在辅助线程里面捕获一个抛出的异常失败,那么你的主线程也同样捕获该异常失败:它所属的进程就会中断。

4、如果你需要通知另一个线程(比如主线程)当前线程中的一个特殊情况,你应该捕捉异常,并简单地将消息发送到其他线程告知发生了什么事。

5、引发异常的线程可以继续执行(如果可能的话),等待指示,或者干脆退出。

 

 

RunloopDemo:iOS开发·RunLoop源码与用法完全解析(输入源,定时源,观察者,线程间通信,端口间通信,NSPort,NSMessagePort,NSMachPort,NSPortMessage)-源码解析 运行循环演示 iOS开发·RunLoop源码与用法完全解析(输入源,定时源,观察者,线程间通信,端口间通信,NSPort,NSMessagePort,NSMachPort,NSPortMessage) 了解更多 简书地址: 立即下载

相关推荐

简单概述人形机器人的“大脑、小脑”

原创 仲翔云人形机器人产业通2024年09月13日 19:41上海人形机器人的大脑和小脑是其控制系统的关键组成部分,它们模拟了人类大脑和小脑的功能,以实现复杂的运动控制和决策过程。

AI生成曾小健3 2070

runlooop

Run loops是线程相关的的基础框架的一部分。一个run loop就是一个事件处理的循环,用来不停的调度工作以及处理输入事件。使用run loop的目的是让你的线程在有工作的时候忙于工作,而没工作的时候处于休眠状态。 Run loop的管理并不完全自动的。你仍然需要设计你的线程代码在合适的时候启动run loop并正确响应输入事件。Cocoa和Core Fundation都提供了run

yohohohoho的专栏 1547

[QDS]从零开始,写第一个Qt Design Studio到程序调用的项目

最近在使用Qt Design Studio进行开发,但是简中网上要不就是只搜得到Qt Designer(Qt Creator内部库),要不就只搜得到一点营销号不知道从哪里搬来的账号,鉴于Qt Design Studio是一个这么强大的软件,自然是需要来进行一下小小的实践的。所以开了这篇文章,方便没有使用过Qt Design Studio 和 QML的开发者也可以快速上手QDS(Qt Design Studio)。在本文中,你将学会如何使用QDS开发一个简单的QML程序,与你的C++后端代码进行交流。

Andius的博客 8213

mach ipc 学习

mach ipc mach kernel提供面向消息的,基于权能的进程间通信。进程间通信(IPC)原语有效地支持许多不同风格的交互,包括远程过程调用(RPC)、面向对象的分布式编程、数据流和发送大量数据。 IPC原语操作于三个抽象:消息、端口和端口集。用户任务通过IPC原语访问所有其他内核服务和抽象。 消息原语让任务发送和接收消息。任务向端口发送消息。发送到端口的消息被可靠地传递(消息可能不会丢失),并按照发送的顺序接收。消息包含一个固定大小的消息头和消息头后面可变数量的类型化数据。报头描述消息的目的地和大

weixin_38849460的博客 989

uniapp实战:mui-player插件如何完美适配m3u8/flv直播流(附完整代码)

本文详细介绍了如何在Uniapp中使用mui-player插件完美适配m3u8和flv直播流,提供从基础配置到高级优化的全流程解决方案。通过动态加载策略、响应式布局和内存管理,实现跨平台稳定播放,适用于企业级直播应用开发。

weixin_29001655的博客 236

EC20模块实战:5步搞定MQTT连接阿里云IoT(附常见错误排查)

本文详细介绍了使用EC20 4G模块通过AT指令连接阿里云IoT平台的完整实战流程。文章以智能农业项目为背景,从硬件接线、网络注册、PDP激活,到MQTT连接配置、一型一密动态注册及数据收发,提供了清晰的5步操作指南,并重点附上了常见错误排查方法,帮助开发者快速实现稳定可靠的物联网设备上云。

weixin_29209801的博客 196

mach port分配的过程分析

1.mach_port_allocate(osfmk\ipc\Mach_port.c)/* * Routine: mach_port_allocate [kernel call] * Purpose: * Allocates a right in a space. Like mach_port_allocate_name, * except that the

dianshanglian的专栏 2511

奥比中光Gemini335L SDK实战:从标定参数到3D点云转换

本文详细介绍了奥比中光Gemini 335L深度相机的SDK实战应用,重点讲解如何跳过繁琐的棋盘格标定,直接调用出厂预标定参数实现高效的3D点云转换。通过解析内参、外参获取及四种核心坐标转换模式,并结合OpenCV等工具,指导开发者快速将相机集成到机器人抓取、三维测量等项目中,实现开箱即用的3D视觉解决方案。

raspberrypi5的博客 639

MAC OS 的mach_port_t和pthread_self()

MAC OS 三种 线程 1.pthread_self() glibc库的线程id。实际上是线程控制块tcb首地址。 2.gettid: 内核级线程id,系统唯一。 该函数为系统调用函数,glibc可能没有该函数声明。 此时需要使用 syscall(SYS_gettid); 3.mach_port_t: mac os特有的id。实际上不能说是thread id,而应该当做是端口。 ...

yxccc的博客 4284

【ComfyUI】QwenImageEdit OOTD角色与姿态匹配换装

本文介绍了一个基于Qwen Edit OOTD 2.0的ComfyUI工作流,能够实现角色与姿态匹配的智能穿搭生成。该工作流通过整合模型推理、姿态识别、图像拼接和渲染等节点,完成从角色图、姿态图到成品穿搭图的完整生成流程。核心采用Qwen Image系列模型进行图像理解和编辑,配合ControlNet进行姿态引导。用户只需提供角色图和姿态参考图,系统即可自动完成姿态解析、语义编码、采样生成等步骤,输出与输入姿态一致的穿搭图像。该方案适用于虚拟角色展示、电商试穿等场景,能保持角色特征一致的同时灵活变换姿态,显

Mr数据杨 1588

【产品】 产品设计:如何解决铝合金氧化着色后表面硬度低的问题(硬质氧化)

1、氧化处理技术 1)化学氧化 化学氧化处理所获得的膜层较薄,一般厚度为0.5μm ~4μm,质软不耐磨,抗蚀能力低于阳极氧化膜。 一般不宜单独便用,由于化学氧化膜吸附能力好,主要作用于油漆的底层,化学氧化按其溶液性可分为碱性和酸性两种。按其膜层性质可分为氧化膜,磷酸盐膜、铬酸盐膜及磷酸一铬酸盐膜等(这类型的氧化膜是可导电)。 2)电化学氧化(阳极氧化) 电化学氧化(俗称阳极氧化)是铝及...

产品线负责人 9736

iOS NSMachPort 线程与进程间的通信

原创:http://blog.youkuaiyun.com/yxh265/article/details/51483822 iOS线程间的通信 iOS中,两个线程之间要想互相通信,可以使用:NSMachPort  下面是例子 #define kMsg1 100 #define kMsg2 101 - (void)viewDidLoad { [super viewDidLoad]; ...

bravegogo的专栏 2260

Flink实战(101):双流join(三)双流中实现Inner Join、Left Join与Right Join

声明:本系列博客是根据SGG的视频整理而成,非常适合大家入门学习。 《2021年最新版大数据面试题全面开启更新》 简介 之前文章中提到JoinedStream与CoGroupedStream,例如下列代码: dataStream.join(otherStream) .where(0).equalTo(1) .window(TumblingEventTimeWindows.of(Time.seconds(3))) .apply { ... } 由于joinedStream与

微信搜:import_bigdata,大数据领域硬核原创作者 737

iOS线程通信和进程通信的例子(NSMachPort和NSTask,NSPipe)

iOS线程间的通信iOS中,两个线程之间要想互相通信,可以使用:NSMachPort 下面是例子#define kMsg1 100 #define kMsg2 101- (void)viewDidLoad { [super viewDidLoad]; //1. 创建主线程的port // 子线程通过此端口发送消息给主线程 NSPort *myPort = [NSMac

yxh265的专栏 1万+

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

OC---IOS开发入门学习(一)

​ objactice-c简称obj-c或者OC。是基于 C 语言的、面向对象的编程语言。他将C语言中复杂繁琐的语法封装的更为简单。代码源文件通常以 .m 扩展名命名(c/c++为.c/.cpp)。m为message代表OC中的消息机制​用于开发 iOS 和 macOS 应用程序。OC完全兼容C语言。类的定义写在源文件中,主要分为两个部分1.类的声明@inteface 类名 :父类名 // NSObject是根类//属性写这里/*方法声明写这里方法声明语法:无参数:- (返回值类型)方法名;

yb941693493的博客 3583

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

带你打造一套APM系统(二)

2.1. Mach 层异常处理大体思路是:先创建一个异常处理端口,为该端口申请权限,再设置异常端口、新建一个内核线程,在该线程内循环等待异常。但是为了防止自己注册的 Mach 层异常处理...

Android技术之家 1460

RunLoop终极解析:输入源,定时源,观察者,线程间通信,端口通信,NSPort,NSMessagePort,NSMachPort,NSPortMessage...

本文Demo传送门 RunloopDemo 前言 OSX / iOS 系统中,提供了两个这样的对象:NSRunLoop 和 CFRunLoopRef。 CFRunLoopRef 是在 CoreFoundation 框架内的,它提供了纯 C 函数的 API,所有这些 API 都是线程安全的。 NSRunLoop 是基于 CFRunLoopRef 的封装,提供了面向对象的 API,但是这些 A...

weixin_33675507的博客 948

[消息传递之五]-NSMatchPort练习

#import @interface ViewController : UIViewController @property (nonatomic) NSMutableArray* NotArray; @property (nonatomic) NSLock* NotLock; @property (nonatomic) NSMachPort* NotPort; @en

灵眼儿上方 1017

进程间通信

原文链接:http://segmentfault.com/blog/cruise/1190000002400329 总起 OS X是MacOS与NeXTSTEP的结合。OC是Smalltalk类面向对象编程与C的结合。iCloud则是苹果移动服务与云平台的结合。 上述都是一些亮点,但是不得不说苹果技术中的进程通讯走的是“反人类”的道路。 由于不是根据每个节点上最优原则进行设计,苹果的进程间

lexiaoyao20的专栏 1353

软件测试之SDK开发(ios)——Mach捕获

Darwin是Mac OS和IOS的操作系统,而XNU是Darwin操作系统的内核部分。XNU是混合内核,兼具宏内核和微内核的特性,而Mach即为其微内核,如图所示: 所以,mach异常是内核层发生的异常。 1、Mach异常的触发和调用流程 Mach异常是最底层的内核异常,用捕获OC异常的方法无法拿到,Mach异常的触发和调用流程如下图所示: 1、硬件产生的信号被Mach层捕获 2、Mach...

lfdanding的专栏 1241

iOS 最好的应用程序开发编程语言竟然是这7种

移动用户将超过 88% 的时间花在移动应用程序上。几乎所有其他企业和商业组织都有其专用的应用程序。拥有如此庞大的智能手机应用程序用户群,学习如何创建一个是个好主意!根据 Exploding Topics 的数据,iPhone 的市场份额相对较高,为 57.93%,高于 Android 的 41.64% 市场份额。事实上,2023 年应用总收入达到了高达 2010 亿美元。由于越来越...

4980

Mac操作系统XNU内核(四)进程间通信

(XNU,是苹果操作系统OS X的内核) OS X系统的全部IPC方式 Shared Memory Mach Messaging(Mach Ports) Distributed Object for Cocoa Apple Events、Distributed Notifications Sockets、Ports and Stream BSD Pipes、BSD ...

weixin_30249203的博客 302

异常处理中throw与throws的异同

愿你时刻保持学习之心,方能成就不世功业 在Java的处理异常机制中,有捕获异常和抛出异常,其中有五个关键字需要谨记try、catch、finally、throw、throws; 其中捕获异常要用到的是try、catch、finally这也是我们在编写代码中用的比较最多,而相对的抛出异常需要用到的就是throw、throws关于捕获异常和抛出异常的区别详情在我博客中有写,有兴趣的同学可自行恰饭。 throw与throws的不同之处: throw表示的是一个动作,表示抛出异常的动作;而throws表示的之一种状

活到老__学到老 586

理解Mach Port

参考文档: 1.http://robert.sesek.com/thoughts/2012/1/debugging_mach_ports.html 2.Mach 3 Kernel Interfaces 3.http://www.foldr.org/~michaelw/log/computers/macosx/task-info-fun-with-mach 3.Ma...

weixin_34364135的博客 412

Mach port right copy的全过程

1. mach_msg_server()(libsyscall\mach\Mach_msg.c)/* * Routine: mach_msg_server * Purpose: * A simple generic server function. Note that changes here * should be considered for duplic

dianshanglian的专栏 1606

Mac操作系统XNU内核(六)Mach Ports

转载于:https://www.cnblogs.com/andypeker/p/4362814.html

weixin_30242907的博客 459
上一篇: iOS核心系统编程最佳实践:安全
下一篇: iOS核心系统编程最佳实践:并发
yangxt
博客等级 码龄20年 172粉丝 78原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值