iOS中的 多线程- NSThread 与 NSObject

本文深入探讨了在iOS应用开发中如何利用NSThread类进行子线程的创建与管理,确保UI界面的流畅性。通过实例展示了在主线程与子线程之间的数据传递与UI更新操作,有效避免了页面假死的问题。同时介绍了如何在不同场景下选择合适的子线程创建方式,如使用detachNewThreadSelector和performSelector等方法,并强调了自动释放池在子线程中的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

// 第一步:
// 封装

// 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]);
    }
}


// 两者都用了自动释放池
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值