@SanMao
2015-08-06T00:31:07.000000Z
字数 2171
阅读 1632
多线程
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
// 线程的新建
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
// 线程开始(start)
[thread start];
NSLog(@"开始执行子线程");
}
- (void)run{
for (int i = 0 ; i< 50; i++) {
NSLog(@"%d",i);
if (i % 5 == 0) {
// 让线程休息2秒(阻塞)
[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:2.0]];
NSLog(@"线程正在休息");
if (i == 30) {
// 结束线程(死亡)
NSLog(@"子线程挂了");
[NSThread exit];
/*简单粗暴地结束方式:return;*/
}
}
}
}
用途:为了解决一块资源被多个线程共享造成的数据紊乱
和数据安全
问题
只要被@synchronized的{}
包裹起来的代码, 同一时刻就只能被一个线程执行
传递一个对象
, 作为锁(一般都是传self)使用同一把锁
才行缩小范围
, 因为范围越大性能就越低atomic
:原子属性,为setter方法加锁(默认就是atomic)nonatomic
:非原子属性,不会为setter方法加锁
对比
atomic系统自动给我们添加的锁不是互斥锁(而是自旋锁)
互斥锁和自旋锁共同点
不同点
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;
// waitUntilDone的含义:
如果传入的是YES: 那么会等到主线程中的方法执行完毕, 才会继续执行下面其他行的代码
如果传入的是NO: 那么不用等到主线程中的方法执行完毕, 就可以继续执行下面其他行的代码
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 执行耗时的异步操作...
dispatch_async(dispatch_get_main_queue(), ^{
// 回到主线程,执行UI刷新操作
});
});
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
// 穿件队列,获取全局并行队列
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
// 添加下载任务到子线程中
dispatch_async(queue, ^{
NSLog(@"%@",[NSThread currentThread]);
// 下载图片
NSURL *url = [NSURL URLWithString:@"http://g.hiphotos.baidu.com/image/pic/item/1b4c510fd9f9d72aee889e1fd22a2834359bbbc0.jpg"];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
// 显示UI控件,将此任务加入到主队列中
// 如果是通过异步函数添加任务,会先执行完所有代码再来执行block中的任务
// 如果是通过同步函数添加的任务,会先执行完block中的任务再执行其他代码
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"%@",[NSThread currentThread]);
self.imageView.image = image;
});
});
}