多线程的替代方法
操作对象(Operation objects):一个操作对象封装了一个在辅助线程执行的任务。隐藏了线程管理的细节。
使用操作队列对象,管理多线程的任务。它利用线程池减少线程创建的开销。
GCD(Grand central Dispatch):
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"Starting: %@", urlString);
UIImage *avatarImage = nil;
NSURL *url = [NSURL URLWithString:urlString];
NSData *responseData = [NSData dataWithContentsOfURL:url];
avatarImage = [UIImage imageWithData:responseData];
NSLog(@"Finishing: %@", urlString);
if (avatarImage) {
dispatch_async(dispatch_get_main_queue(), ^{
self.image = avatarImage;
});
dispatch_async(dispatch_get_main_queue(), completion);
}
else {
NSLog(@"-- impossible download: %@", urlString);
}
});
Idle-tieme通知:对于优先级很低的任务,可以再接到系统空闲通知的时候处理任务。
异步函数:
定时器:
分开处理:比如可以将一个大数据运算交由一个单独的服务器来处理
线程通信机制
直接发送消息:通过performSelector在另一线程的上下文执行
全局变量,共享内存和对象:必须用锁或者其它同步机制保证数据的正确性
条件:
Runloop源:通过一个自定义的消息源将消息发给另一个线程。
端口和socket:
消息队列:
cocoa分布对象:
POSIX互斥锁
pthread_mutex_t mutex;
initFunction()
{
pthread_mutex_init(&mutex, NULL);
}
MyFunction()
{
pthread_mutex_lock(&mutex);
// ...
pthread_mutex_unlock(&mutex);
}
NSLock类
NSLock类实现NSLocking协议,并增加了tryLock和lockBeforeDate方法。
NSLock* lock = [NSLock new];
if ([lock tryLock]) {
[lock unlock];
}
@synchronized指令
创建给@synchronized 指令的对象是一个用来区别保护块的唯一标示符。如果你 在两个不同的线程里面执行上述方法,每次在一个线程传递了一个不同的对象给 anObj 参数,那么每次都将会拥有它的锁,并持续处理,中间不被其他线程阻塞。
作为一种预防措施,@synchronized 块隐式的添加一个异常处理例程来保护代码。
该处理例程会在异常抛出的时候自动的释放互斥锁。这意味着为了使用 @synchronized 指令,你必须在你的代码中启用异常处理。
如果你不想让隐式的异 常处理例程带来额外的开销,你应该考虑使用锁的类。
NSRecursiveLock
NSRecursiveLock 类定义的锁可以在同一线程多次获得,而不会造成死锁。一个 递归锁会跟踪它被多少次成功获得了。每次成功的获得该锁都必须平衡调用锁住和解 锁的操作。只有所有的锁住和解锁操作都平衡的时候,锁才真正被释放给其他线程获 得。
一般用在递归函数中防止递归阻塞线程。
NSConditionLock
使用特定整型值来锁住和解锁。消费者使用程序制定的整型值来获取锁,生产者完成时将锁设置成合适的整型值唤醒消费者线程。lock-》unlockWithCondition,lockWhenCondition->unlock或者任意组合。
condLock lockWhenCondition:HAS_DATA];
/* Remove data from the queue. */
[condLock unlockWithCondition:(isEmpty ? NO_DATA : HAS_DATA)];
NSDistributedLock
可以被多台主机上的多个应用程序使用来限制对某些共享 资源的访问,比如一个文件。锁本身是一个高效的互斥锁,它使用文件系统项目来实 现,比如一个文件或目录。
NSDistributedLock 并没有实现 NSLocking 协议,所有它没 有 lock 方法。提供了一个 tryLock 方法,并 让你决定是否轮询。可以通过调用 unlock 方法来释放它。
使用 breadLock 方法来打破现存的 锁以便你可以获取它。
cocoaCondition
//消费者
[cocoaCondition lock];

while (timeToDoWork <= 0)

[cocoaCondition wait];

timeToDoWork--;
// Do real work here.
 [cocoaCondition unlock];
//生产者
[cocoaCondition lock];
timeToDoWork++;
[cocoaCondition signal];
[cocoaCondition unlock];