页面的假死
1.同步请求Data总成的UI假死
//dataWithContentsOfURL这个方法耗时
NSURL *url = [NSURL URLWithString:@"http://pic.nipic.com/2007-11-09/200711912453162_2.jpg"];
NSData *imageData = [NSData dataWithContentsOfURL:url];
// 显示image
self.photoImageView.image = [UIImage imageWithData:imageData];
2.开辟子线程, 解决页面假死的问题
[NSThread detachNewThreadSelector:@selector(threadAction) toTarget:self withObject:nil];
- (void)threadAction {
@autoreleasepool {
//dataWithContentsOfURL这个方法耗时
NSURL *url = [NSURL URLWithString:@"http://pic.nipic.com/2007-11-09/200711912453162_2.jpg"];
//跟UI界面相关的要回到主线程处理
[self performSelectorOnMainThread:@selector(backMainThrad:) withObject:imageData waitUntilDone:YES];
}
}
//回到主线程中执行的方法
- (void)backMainThrad:(NSData *)imageData {
// 显示image
self.photoImageView.image = [UIImage imageWithData:imageData scale:1];
}
线程间通讯
线程之间的跳转
主线程->子线程
子线程->主线程
子线程->子线程
// 子线程->主线程的两个方法
//1.
dispatch_async(dispatch_get_main_queue(), ^{
// 回到主线程
// block中的任务在主线程中执行
});
//2.
[self performSelectorOnMainThread:@selector(mainThreadAction) withObject:nil waitUntilDone:YES];
// 子线程->子线程
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//在子线程中执行
NSThread *createThread = [[NSThread alloc] init];
createThread.name = @"other";
[self performSelector:@selector(otherTheardAction) onThread:createThread withObject:nil waitUntilDone:YES];
});
}
//验证已经跳转到名字为other的子线程中了
- (void)otherTheardAction{
NSLog(@"---%@", [NSThread currentThread]);
}
- (void)mainThreadAction{
NSLog(@"在主线程中执行");
}
线程互斥 ##eg.卖票
模拟3个窗口卖票, 其实就是3个线程
线程数据错乱, 线程的数据安全的问题
// 我们加的锁都属于互斥锁
// 1.@synchronized锁
// 2.NSlock锁
// 2.创建锁对象
NSLock *lock = [[NSLock alloc] init];
for (int i = 0; i < 3; i++) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
/*
@synchronized(self) {
// 对数据的操作, 这些操作对于线程而言, 只能有一个线程执行, 别的俩个只能等待
//在子线程中操作的代码
while (self.count > 0) {
NSLog(@"count = %ld", self.count);
self.count--;
}
}
*/
[lock lock];
while (self.count > 0) {
NSLog(@"count = %ld", self.count);
self.count--;
}
[lock unlock];
});
}