一个NSThread对象就代表一条线程
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
[thread start];
// 线程一启动,就会在线程thread中执行self的run方法
//设置名字
- (void)setName:(NSString *)n;
- (NSString *)name;
创建线程后自动启动线程
[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];
或者
//隐式创建并启动线程
[self performSelectorInBackground:@selector(run) withObject:nil];
上述2种创建线程方式的优缺点
+ 优点:简单快捷,不用手动调用start方法, 系统会自动启动
+ 缺点:无法对线程进行更详细的设置
主线程相关用法
+ (NSThread *)mainThread; // 获得主线程
- (BOOL)isMainThread; // 是否为主线程
+ (BOOL)isMainThread; // 是否为主线程
获得当前线程
NSThread *current = [NSThread currentThread];
线程的名字
- (void)setName:(NSString *)n;
- (NSString *)name;
// 阻塞当前线程
// [NSThread sleepForTimeInterval:2.0];
[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:2.0]];
//线程死亡
[NSThread exit];
多个线程可能同时对同一个资源进行访问,这就有可能会产生资源竞争
。
为了解决这个问题,可以使用互斥锁
互斥锁使用格式
{ // 需要锁定的代码 }
注意:锁定1份代码只用1把锁,用多把锁是无效的
互斥锁的优缺点
互斥锁的使用前提:多条线程抢夺同一块资源
相关专业术语:线程同步
在开发中, 如果要加锁, 一般情况都使用self
@synchronized(self)
{
}
OC在定义属性时有nonatomic和atomic两种选择
注意点:
atomic系统自动给我们添加的锁不是互斥锁,而是自旋锁
如果是互斥锁,假如现在被锁住了,那么后面来得线程就会进入”休眠”状态, 直到解锁之后, 又会唤醒线程继续执行
如果是自旋锁, 假如现在被锁住了, 那么后面来得线程不会进入休眠状态, 会一直傻傻的等待, 直到解锁之后立刻执行
自旋锁更适合做一些较短的操作
举例:
通常在子线程中做一些
比较耗时间的操作,比如图片的下载,然后在主线程中更新UI
创建子线程,在里面下载图片
NSURL *url = [NSURL URLWithString:@"http://b.hiphotos.baidu.com/image/pic/item/e4dde71190ef76c666af095f9e16fdfaaf516741.jpg"];
[self performSelectorInBackground:@selector(download2:) withObject:url];
回到主线程更新UI
- (void)download2:(NSURL *)url
{
// 在子线程下载图片
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
// 回到主线程,方法一
//[self performSelectorOnMainThread:@selector(showImage:) withObject:image waitUntilDone:YES];
// 回到主线程,方法二
//[self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:YES];
// 回到主线程,方法三
[self performSelector:@selector(showImage:) onThread:[NSThread mainThread] withObject:image waitUntilDone:YES];
//[self performSelectorOnMainThread:@selector(showImage:) withObject:image waitUntilDone:NO];
}
[self performSelectorInBackground:@selector(download2:) withObject:url];
[self performSelectorOnMainThread:@selector(showImage:) withObject:image waitUntilDone:YES];
[self performSelectorOnMainThread:@selector(showImage:) withObject:image waitUntilDone:NO];
[self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:YES];
[self performSelector:@selector(showImage:) onThread:[NSThread mainThread] withObject:image waitUntilDone:YES];