// 第一步:
// 封装
// Thread,主线程与 UI 挂钩
// 注意:
// ***使用 NSThresd时候,在子线程中要自己加,@autoreleasepool, 不加会内存泄露(对象释放不了), 原因:autoreleasepool 影响一些autoreleasepool标签的对象释放, 但是,主线程已经加到自动释放池中了
- (void)objectCreate {
-
// 1.对象创建方式,使用NSThread创建一个子线程, object 是 nil,则不需要参数
NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(objectThread:) object:self];
// 线程名字
thread.name = @"shaoqiong";
// 对象的创建方式需要手动的执行(类似)
[thread start];
// thread的cancel只能取消还没有开始执行的任务,任务已经开始的话,是取消不了的, 其实这个 cancel 就相当于给这个线程的 isCancel 属性设置成了 YES
//NSThread对象的一些属性
// thread.isExecuting,---当前线程对象是否处于执行状态
// thread.isFinished---判断当前线程对象是否结束运行
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// 对象方法
[thread cancel];
});
}
// objectThread方法实现
// 在下面方法中执行的操作都是在子线程中执行的
- (void)objectThread:(id)sender {
@autoreleasepool {
NSLog(@"----%@",sender);
for (int i = 0; i < 10000000; i++) {
if (i == 100) {
// 终止该线程,类方法
[NSThread exit];
}
NSLog(@"----%d",i);
}
}
}
//NSThread类方法创建 detachNewThreadSelector
- (void)classCreate {
[NSThread detachNewThreadSelector:@selector(classThread) toTarget:self withObject:nil];
// 几个类方法
// 1. ****[NSThread isMainThread], 判断是否在主线程 YES,就是当前线程-主线程, NO-子线程
// 2. [NSThread currentThread],获取当前的线程
}
// target - action, NSThread的方法都是在子线程
- (void)classThread {
NSLog(@"在子线程中, isMainThread:%d",[NSThread isMainThread]);
}
// 实际项目: 从 url 上获得的大图片显示在 viewControll 上
- (IBAction)butonAction:(id)sender {
// 1.同步请求 Data 造成的 UI 假死
// dataWithContentsOfURL,这个方法非常耗时
// NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://pic.nipic.com/2007-11-09/200711912453162_2.jpg"]];
// // 显示 image
// self.photoImageView.image = [UIImage imageWithData:imageData scale:1.0];
//
// 第一步:
// 2.开辟子线程,解决页面假死的问题
[NSThread detachNewThreadSelector:@selector(threadAction) toTarget:self withObject:nil];
}
// 第二步:
- (void)threadAction {
@autoreleasepool {
// 耗时的
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://pic.nipic.com/2007-11-09/200711912453162_2.jpg"]];
// 2.主线程,刷新界面
[self performSelectorOnMainThread:@selector(backMainthread:) withObject:imageData waitUntilDone:YES];
}
}
// 第三步:
// 回到主线程执行的方法, 刷新界面
- (void)backMainthread:(NSData *)imageData {
// 显示 image, UI刷新界面,在主线程
self.photoImageView.image = [UIImage imageWithData:imageData scale:1.0];
}
// 第二种 NSObject
// 使用 NDObject类中方法开辟子线程, self表示类的对象
[self performSelectorInBackground:@selector(backgroundAction) withObject:nil];
}
// 在子线程中执行的方法
// **注意: 在下面方法中, 处理 UI 界面的东西,记得回到主线程
// **1.NSThread, 2.NSObject这两种技术,都需要加上自动释放池(ARC,MRC 都需要加上)
- (void)backgroundAction {
@autoreleasepool {
NSLog(@"---是子线程%d", [NSThread isMainThread]);
}
}
// 两者都用了自动释放池
iOS中的 多线程- NSThread 与 NSObject
最新推荐文章于 2024-05-29 19:51:45 发布