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 ...
随机推荐
- 爬虫框架Scrapy之详解
Scrapy 框架 Scrapy是用纯Python实现一个为了爬取网站数据.提取结构性数据而编写的应用框架,用途非常广泛. 框架的力量,用户只需要定制开发几个模块就可以轻松的实现一个爬虫,用来抓取网页 ...
- spark SQL学习(案例-统计每日uv)
需求:统计每日uv package wujiadong_sparkSQL import org.apache.spark.sql.{Row, SQLContext} import org.apache ...
- url拼接
在做网页抓取的时候经常会遇到一个问题就是页面中的链接是相对链接,这个时候就需要对链接进行url拼接,才能得到绝对链接. url严格按照一定的格式构成,一般为如下5个字段: 详细可参考RFC:http: ...
- Mysql数据库实用语句集
mysql实用语句 (1).从第0行开始取,取3行(一般用于分页)select * from student limit 0,3 (2).查看当前数据库编码 show variables like ' ...
- Matlab 实现对码功能
1.什么叫对码? 举例说明,数据库中有两张表. 表 1: 编号 描述 儿科门诊 妇科门诊 产科门诊 表 2: 编号 描述 儿科门诊 妇科门诊 产科门诊 现在要在表 1 和表 2 之间找到一一对应.比如 ...
- linux ps 命令参数详解
-a 显示所有终端机下执行的进程,除了阶段作业领导者之外. a 显示现行终端机下的所有进程,包括其他用户的进程. -A 显示所有进程. -c 显示CLS和PRI栏位. c 列出进程时,显示每个进程真正 ...
- Memcached gets 命令
Memcached gets 命令获取带有 CAS 令牌存 的 value(数据值) ,如果 key 不存在,则返回空. 语法: gets 命令的基本语法格式如下: gets key 多个 key 使 ...
- Servlet与线程安全
先说结论:servlet不是线程安全的. servlet运行过程 Servlet程序是由WEB服务器调用,web服务器收到客户端的Servlet访问请求后: ①Web服务器首先检查是否已经装载并创建了 ...
- UVALive - 6712 lca+dfs序线段树
题意:一棵树q次查询,每次查询给三个不同的点,要求计算到这三个点的比其他两个距离都要小的点数 题解:很明显的lca,倍增的找中点,关键是两个点的中点很好找,但是三个点不好找,我刚开始还准备分类讨论,后 ...
- jq对页面元素进行排序
利用sort函数排序: var div = $('.media').toArray().sort(function(a,b){ return parseInt($(a).find('.info .pr ...