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) 了解更多 简书地址: 立即下载

相关推荐

计算机网络简答题

协议定义了在两个或多个通信实体之间交换的报文格式和顺序,以及发送接收报文以及其他事件需要采取的操作。为。

m0_61636632的博客 1699

runlooop

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

yohohohoho的专栏 1547

【阅读文献笔记】FoundationStereo: Zero-Shot Stereo Matching

提出首个零样本泛化立体匹配基础模型设计 STA 模块融合单目先验提出 AHCF 模块增强代价滤波构建 100 万合成数据集 FSD + 自净化流程。

qq_46460379的博客 1257

mach ipc 学习

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

weixin_38849460的博客 989

基于APDL语言的结构优化设计

同理,二次微分值称为二阶值。通俗地讲优化分析,指的找到一种方案可以满足所有的设计要求,而且所需的支出(如重量,面积,体积,应力,费用等)最小。设计方案的任何方面都是可以优化的,比如说:尺寸(如厚度),形状(如过渡圆角的大小),支撑位置,制造费用,自然频率,材料特性等。完成分析文件的建立后,就可以进行优化分析了,如果在交互方式下进行优化的话,最好先在ANSYS数据库中用分析文件建立参数,其优点有:初始参数可以作为一阶分析方法的起点,且对于优化过程参数在数据库中可以在GUI下进行操作,便于定义优化变量。

m0_73816777的博客 1176

国产大模型编程能力深度分析报告(2026年5月更新版)

2026年5月国产大模型编程能力报告显示,主流模型迎来重大升级。DeepSeek V4以1.6T参数创性能新高,Qwen3.6-Plus支持原生多模态编程,MiniMax M2.7转向闭源并优化Agent编码,Kimi K2.6成为商业化成熟的主力模型,GLM-5开源并涨价30%。阿里云百炼推出双轨订阅体系,区分团队和个人开发者需求。各模型在参数规模、上下文长度、性能表现和适用场景上各具优势,国产AI编程服务正加速向订阅制转型,成本效益显著提升。

Willin Wang 的全栈升级指南 1653

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

Ansys Lumerical实战:5步搞定Mach-Zehnder调制器多物理场仿真(附眼图分析技巧)

本文详细介绍了使用Ansys Lumerical进行行波马赫-曾德尔调制器多物理场仿真的完整流程。通过CHARGE、MODE和INTERCONNECT三大模块的协同工作,从电学参数提取、光学射频特性分析到系统级眼图评估,分步解析了高效仿真与性能优化的核心技巧,为硅光调制器设计提供了实战指南。

weixin_29056781的博客 542

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

大白话讲解Numpy中什么是一维、二维、三维数组,以及5种创建方式

NumPy中提供了多种创建数组的方式,其中最基本的方式就是通过array()函数创建数组在使用该函数时直接传入列表或元组即可。 通过array()函数分别创建一维数组、二维组和三维数组,那么什么是维度呢?一维、二维、三维有什么区别? 1、什么是维度? 维度可以理解为描述数据的一种 “方向” 或者 “层次”。在数组中,维度的数量决定了我们需要用多少个索引来访问一个元素 2、一维、二维、三维的区别? (1)一维:一维数组就像是一条直线上排列的一组数据,例如: a = np.array([1, 2

1365

Python李峋同款跳动的爱心(完整代码)

Python语言实现李峋同款可写字版跳动的爱心的完整代码。

AIGC 4万+

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

基于STM32设计的智能水产养殖系统(华为云IOT)(152)

当前设计的智能水产养殖系统主控芯片采用STM32F103RCT6,可以实现对水位、水温、水混浊度和PH值等参数的监测和控制,并且支持定时投喂功能。通过连接华为云物联网平台,将传感器数据上传到服务器,并通过Qt设计的Android手机APP来获取设备上传的数据,从而实现对养殖环境的远程监测和控制。

8828

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

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

yxh265的专栏 1万+

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

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

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

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

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

Android技术之家 1460

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

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、付费专栏及课程。

余额充值