IOS开发 基础框架(Fondation Framework)的线程安全
有一种误解,认为基础框架(Foundation framework)是线程安全的,而Application Kit是非线程安全的。不幸的是,这是一个总的概括,从而造成一点误导。每个框架都包含了线程安全部分和非线程安全部分。以下部分介绍Foundation framework里面的线程安全部分。
线程安全的类和函数
下面这些类和函数通常被认为是线程安全的。你可以在多个线程里面使用它们的同一个实例,而无需获取一个锁。
- NSArray
- NSAssertionHandler
- NSAttributedString
- NSCalendarDate
- NSCharacterSet
- NSConditionLock
- NSConnection
- NSData
- NSDate
- NSDecimal functions
- NSDecimalNumber
- NSDecimalNumberHandler
- NSDeserializer
- NSDictionary
- NSDistantObject
- NSDistributedLock
- NSDistributedNotificationCenter
- NSException
- NSFileManager (in Mac OS X v10.5 and later)
- NSHost
- NSLock
- NSLog/NSLogv
- NSMethodSignature
- NSNotification
- NSNotificationCenter
- NSNumber
- NSObject
- NSPortCoder
- NSPortMessage
- NSPortNameServer
- NSProtocolChecker
- NSProxy
- NSRecursiveLock
- NSSet
- NSString
- NSThread
- NSTimer
- NSTimeZone
- NSUserDefaults
- NSValue
- 还有对象的allocation和retain函数
- Zone和内存函数
非线程安全类
以下这些类和函数通常被认为是非线程安全的。在大部分情况下,你可以在任何线程里面使用这些类,只要你在同一个时间只在一个线程里面使用它们。参考这些类对于的额外详细信息的文档。
- NSArchiver
- NSAutoreleasePool
- NSBundle
- NSCalendar
- NSCoder
- NSCountedSet
- NSDateFormatter
- NSEnumerator
- NSFileHandle
- NSFormatter
- NSHashTable functions
- NSInvocation
- NSJavaSetup functions
- NSMapTable functions
- NSMutableArray
- NSMutableAttributedString
- NSMutableCharacterSet
- NSMutableData
- NSMutableDictionary
- NSMutableSet
- NSMutableString
- NSNotificationQueue
- NSNumberFormatter
- NSPipe
- NSPort
- NSProcessInfo
- NSRunLoop
- NSScanner
- NSSerializer
- NSTask
- NSUnarchiver
- NSUndoManager
- User name and home directory functions
注意,尽管NSSerializer,NSArchiver,NSCoder和NSEnumerator对象本身是线程安全的,但是它们被放置这这里是因为当它们封装的对象被使用的时候,更改这些对象数据是不安全的。比如,在归档情况下,修改被归档的对象是不安全的。对于一个枚举,任何线程修改枚举的集合都是不安全的。
只能用于主线程的类
以下的类必须只能在应用的主线程类使用。
- NSAppleScript
可变 vs 不可变
不可变对象通常是线程安全的。一旦你创建了它们,你可以把它们安全的在线程间传递。当前,在使用不可变对象时,你还应该记得正确使用引用计数。如果不适当的释放了一个你没有引用的对象,你在随后有可能造成一个异常。
可变对象通常是非线程安全的。为了在多线程应用里面使用可变对象,应用应该使用锁来同步访问它们(关于更多信息,参见“原子操作”部分)。通常情况下,集合类(比如,NSMutableArray,NSMutableDictionary)是考虑多变时是非线程安全的。这意味着,如果一个或多个线程同时改变一个数组,将会发生问题。你应该在线程读取和写入它们的地方使用锁包围着。
即使一个方法要求返回一个不可变对象,你不应该简单的假设返回的对象就是不可变的。依赖于方法的实现,返回的对象有可能是可变的或着不可变的。比如,一个返回类型是NSString的方法有可能实际上由于它的实现返回了一个NSMutableString。如果你想要确保对象是不可变的,你应该使用不可变的拷贝。
可重入性
可重入性是可以让同一对象或者不同对象上一个操作“调用”其他操作成为可能。保持和释放对象就是一个有可能被忽视的”调用”的例子。
以下列表列出了Foundation framework的部分显式的可重入对象。所有其他类可能是或可能不是可重入的,或者它们将来有可能是可重入的。对于可重入性的一个完整的分析是不可能完成的,而且该列表将会是无穷尽的。
- Distributed Objects
- NSConditionLock
- NSDistributedLock
- NSLock
- NSLog/NSLogv
- NSNotificationCenter
- NSRecursiveLock
- NSRunLoop
- NSUserDefaults
类的初始化
Objective-C的运行时系统在类收到其他任何消息之前给它发送一个initialize消息。这可以让类有机会在它被使用前设置它的运行时环境。在一个多线程应用里面,运行时保证仅有一个线程(该线程恰好发送第一条消息给类)执行initialized方法,第二个线程阻塞直到第一个线程的initialize方法执行完成。在此期间,第一个线程可以继续调用其他类上的方法。该initialize方法不应该依赖于第二个线程对这个类的调用。如果不是这样的话,两个线程将会造成死锁。
自动释放池(Autorelease Pools)
每个线程都维护它自己的NSAutoreleasePool的栈对象。Cocoa希望在每个当前线程的栈里面有一个可用的自动释放池。如果一个自动释放池不可用,对象将不会给释放,从而造成内存泄露。对于Application Kit的主线程通常它会自动创建并消耗一个自动释放池,但是辅助线程(和其他只有Foundationd的程序)在使用Cocoa前必须自己手工创建。如果你的线程是长时间运行的,那么有可能潜在产生很多自动释放的对象,你应该周期性的销毁它们并创建自动释放池(就像Application Kit对主线程那样)。否则,自动释放对象将会积累并造成内存大量占用。如果你的脱离线程没有使用Cocoa,你不需要创建一个自动释放池。
Run Loops
每个线程都有一个或多个run loop。然而每个run loop和每个线程都有它自己的输入模式来决定run loop运行的释放监听那些输入源。输入模式定义在一个run loop上面,不会影响定义在其他run loop的输入模式,即使它们的名字相同。
如果你的线程是基于Application Kti的话,主线程的run loop会自动运行,但是辅助线程(和只有Foundation的应用)必须自己启动它们的run loop。如果一个脱离线程没有进入run loop,那么线程在完成它们的方法执行后会立即退出。
尽管外表显式可能是线程安全的,但是NSRunLoop类是非线程安全的。你只能在拥有它们的线程里面调用它实例的方法。
IOS开发 基础框架(Fondation Framework)的线程安全的更多相关文章
- iOS开发基础框架
---恢复内容开始--- //appdelegate //// AppDelegate.m// iOS开发架构//// Copyright © 2016年 Chason. All rights ...
- IOS开发基础知识碎片-导航
1:IOS开发基础知识--碎片1 a:NSString与NSInteger的互换 b:Objective-c中集合里面不能存放基础类型,比如int string float等,只能把它们转化成对象才可 ...
- iOS开发——总结篇&IOS开发基础知识
IOS开发基础知识 1:Objective-C语法之动态类型(isKindOfClass, isMemberOfClass,id) 对象在运行时获取其类型的能力称为内省.内省可以有多种方法实现. 判断 ...
- IOS开发基础环境搭建
一.目的 本文的目的是windows下IOS开发基础环境搭建做了对应的介绍,大家可根据文档步骤进行mac环境部署: 二.安装虚拟机 下载虚拟机安装文件绿色版,点击如下文件安装 获取安装包: ...
- iOS开发基础-九宫格坐标(6)
继续对iOS开发基础-九宫格坐标(5)中的代码进行优化. 优化思路:把字典转模型部分的数据处理操作也拿到模型类中去实现,即将 ViewController 类实现中 apps 方法搬到 WJQAppI ...
- iOS开发基础-九宫格坐标(5)
继续在iOS开发基础-九宫格坐标(4)的基础上进行优化. 一.改进思路 1)iOS开发基础-九宫格坐标(4)中 viewDidLoad 方法中的第21.22行对控件属性的设置能否拿到视图类 WJQAp ...
- iOS开发基础-九宫格坐标(4)
对iOS开发基础-九宫格坐标(3)的代码进行进一步优化. 新建一个 UIView 的子类,并命名为 WJQAppView ,将 appxib.xib 中的 UIView 对象与新建的视图类进行关联. ...
- iOS开发基础-九宫格坐标(3)之Xib
延续iOS开发基础-九宫格坐标(2)的内容,对其进行部分修改. 本部分采用 Xib 文件来创建用于显示图片的 UIView 对象. 一.简单介绍 Xib 和 storyboard 的比较: 1) X ...
- iOS开发基础-九宫格坐标(2)之模型
在iOS开发基础-九宫格(1)中,属性变量 apps 是从plist文件中加载数据的,在 viewDidLoad 方法中的第20行.26行中,直接通过字典的键名来获取相应的信息,使得 ViewCont ...
随机推荐
- 纯js提交get和post请求
get function get(URL, PARAMS) { var temp = document.createElement("form"); temp.method = & ...
- sonar总结--
maven的setting.xml 配置 https://www.cnblogs.com/javawebsoa/p/3206504.html
- Nginx的坑
Nginx的重启命令:./nginx -s reload 有时候没有效果,原因不知, 要重启可以使用:killall nginx,然后./nginx (就是先kill掉Nginx,然后再重启Ngi ...
- zoom:1;
zoom:1;属性是IE浏览器的专有属性,可以设置或检索对象的缩放比例.触发ie的hasLayout属性.清除浮动.清除magin的重叠等. 注意:它未通过W3C验证.
- bootstrap系统学习
1.响应式中注意的内容: 一行(row)必须在.container中. col-xs- col-sm- col-md- col-lg- 列偏移 .col-md-offset-* 列排序 .col-md ...
- 第五章 如何使用Burp Target
Burp Target 组件主要包含站点地图.目标域.Target 工具三部分组成,他们帮助渗透测试人员更好地了解目标应用的整体状况.当前的工作涉及哪些目标域.分析可能存在的攻击面等信息,下面我们就分 ...
- 转:25个Java机器学习工具和库
转自:http://www.cnblogs.com/data2value/p/5419864.html 本列表总结了25个Java机器学习工具&库: 1. Weka集成了数据挖掘工作的机器学习 ...
- Shell_NotifyIcon托盘图标闪烁
之前的同事留下了一个程序会莫名闪退的bug,今天终于发现是托盘图标闪烁使得gdi资源耗尽导致的. 先定义 #include "shellapi.h" //托盘图标引用 NOTIFY ...
- 河南省多校联盟二-F 线段树+矩阵
---恢复内容开始--- 1284: SP教数学 时间限制: 2 秒 内存限制: 128 MB提交: 24 解决: 4 题目描述 输入 输出 对于每组数据的2操作,输出一行对1e9 + 7取模的答 ...
- jQuery-轮播图(友善滴滚动切换)
线上实例:http://lgy.1zwq.com/slide/ [处理] 这里的图片滚动轮播,做了点小处理:当在第1页状态时,你点击第5页,图片的滚动是一张滑过,而不是从2-3-4-5(这种的多张滚动 ...