NSOperationQueue高级运用:管理和调度里面线程池

iOS多线程——你要知道的NSOperation都在这里 你要知道的iOS多线程NSThread、GCD、NSOperation、RunLoop都在这里转载请注明出处 http://www.jianshu.com/p/bf0916ee1492本系列文章主要讲解iOS中多线程的使用,包括:NSThread、GCD、NSOperation以及RunLoop的使用方法详解,本系列文章不涉及基础的线程/进程、同步/异步、阻塞/非阻塞、串行/并行,这些基础概念,有不 阅读详情

    当你使用NSOperationQueue的时候,怎么按照你自己的意愿去管理每一个你add进去的NSOperation(进程的优先级,相同线程请求操作的新旧替换)


阅读本文需要理解KVO && KVC(个人认为,如果想成为一个越来越好的IOS developer,这个是必须要懂得的,还有core data)


一.demo(多线程下载图片):控制NSOperation执行的优先级,并且限制最大线程执行数目,若已经达到最大线程执行数目,又有新的线程进入队列,那么停止最老的一个线程,把他的位置让给最新进入的线程:

(为什么有最大线程个数的限制:主要考虑的是在移动网络的情况下,网络上行和下行带宽的限制,给用户一个较好的体验,而不是闲线程过多时消耗过大,毕竟IOS不是MTK~)

1.自定义一个自己的NSOperationQueue:主要为了在NSOperationQueue init的时候加入一行代码

-(id)init

{

    if (self = [superinit]) {

        [selfsetMaxConcurrentOperationCount:10];

        [selfaddObserver:selfforKeyPath:@"operations"options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOldcontext:nil];

    }

    returnself;

}


2.上行代码让你监控了NSOperationQueue 中的 NSOperation NSArray的变化,当有变化的时候,你会收到消息

我下面的代码是写一个(后进先执行的 进程队列管理)

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if ([keyPath isEqualToString:@"operations"])
    {
        NSArray *oldOperation = [change objectForKey:@"old"];//变化之前的NSOperation Array
        NSArray *newOperation = [change objectForKey:@"new"];//新的的NSOperation Array
 
//!注意A:此时队列里的所有线程仍然在执行,所以你此时取出的线程新旧数组,仅仅是一个参考值(他们可能其中一个在此时已经执行完毕了)


//第一个NSOperation加入,无需处理
        if (newOperation.count == 1) {
            return;
        }
        
        //进入的线程个数没有超过你设定的最大线程个数,所以无需管理他的优先级,因为所有的线程都在运行
        if (self.operationCount <= self.maxConcurrentOperationCount) {
            NSLog(@"add one operation to queue.do not need to change operation priority level");
            return;
        }
        //进入线程队列的线程个数过多,所以停止最老的一个线程,执行最新的线程
        if (newOperation.count > oldOperation.count) {
            //先停止整个线程执行队列:若不停止,你这段代码执行的同时,其余线程仍然在执行,此时你所取的一些状态值只是一个参考值,很有可能在你代码执行了2行后,有一个线程就执行完毕了!
            [self setSuspended:YES];
            NSOperation *operation;
   //需要停止的线程个数
            int needcancelNum = self.operationCount - self.maxConcurrentOperationCount;
            int i = 0;
            for (operation in newOperation) {
                if ([operation isFinished]) {
   //一个线程已经执行完毕:为什么:参照 注意A
                    needcancelNum--;
                    NSLog(@"%@ is finished", operation);
                }else if(i < needcancelNum)
                {
   //取消最旧的线程执行
                    [operation cancel];
                    NSLog(@"%@ is canceld", operation);
                    i++;
                }else
                {
   //将其余所有线程的优先级设置为0.8
                    operation.threadPriority = 0.8;
                }
            }
   //此时operation 是最新的一个线程,将其优先级设置为1.0(最高)
            operation.threadPriority = 1.0;
   //恢复线程队列的运行
            [self setSuspended:NO];
        }
    }
}


二:相同线程请求操作的新旧替换

如何识别一个线程的功能是相同的

(使用场景:由于用户的刷新操作,你需要下载最新网络数据对应的图片,此时若前一次网络需要下载的图片还没有下载完成,你需要用你最新的线程去替换旧的线程)

我想到的方案是,用一个自己定义过的NSOperation,在里面加入一个属性,线程名字。

这样在上文所述 线程队列的NSOperation数组发生了变化时,你可以查询所有线程的名字,然后检测下是否有相同名字的线程进入了线程队列,如果有的话,你需要取消旧的那个线程。

一样在

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 中加入以下代码:   PicLoadAndCacheOperation 是一个custom NSOperation


//new operation comes more than 1,so check Did their have the same name
        if((newOperation.count - oldOperation.count) > 1)
        {
            [self setSuspended:YES];
            for (int i = 0; i < newOperation.count; i++)
            {
                PicLoadAndCacheOperation *keyOperation = [newOperation objectAtIndex:i];
                
                for (int j = i + 1; j < newOperation.count; j++)
                {
                    PicLoadAndCacheOperation *comparedOperation = [newOperation objectAtIndex:j];
                    if ([comparedOperation.operationName isEqualToString:keyOperation.operationName])
                    {
                        [keyOperation cancel];
                        continue;
                    }
                }
            }
            [self setSuspended:NO];
        }
        //instead last thread by new thread by it's operation name
        else if ((newOperation.count - oldOperation.count) == 1) {
            [self setSuspended:YES];
            PicLoadAndCacheOperation *Operation = [newOperation objectAtIndex:oldOperation.count];
            NSString *newOperationName = Operation.operationName;
            
            for (PicLoadAndCacheOperation *oOperation in oldOperation) {
                NSString *oldOperationName = oOperation.operationName;
                if ([oldOperationName isEqualToString:newOperationName]) {
                    [oOperation cancel];
                    [self setSuspended:NO];
                    return;
                }
            }
            [self setSuspended:NO];
        }

第4章-上下文管理-对话历史记忆系统与窗口优化-《Agentic AI 智能体应用开发》 当上下文窗口接近极限时,需要对已有内容进行压缩。压缩不是简单的截断——你需要保留核心语义,去除冗余。# Python: 对话摘要压缩# 使用 Haiku 做摘要任务,成本最低"""将一段对话历史压缩为摘要"""system="你是一个对话摘要专家。请生成简洁但有信息量的摘要。",f"'用户' 阅读详情

相关推荐

Unity Android构建报错:compileSdk 35兼容性五层定位法

Android构建中的compileSdk是编译时API目标版本,其升级并非孤立操作,而是触发JDK、Android Gradle Plugin(AGP)、NDK、targetSdk与Unity引擎版本之间强耦合校验的起点。当出现'using a newer Android Gradle plugin to use compileSdk = 35'类报错,本质是代际技术栈错配——例如AGP 7.1.3不识别compileSdk 35所需Java 17语法,或NDK 21与AGP 7.4的ABI规范冲突。该问

weixin_32496547的博客 566

iOS多线程:『NSOperation、NSOperationQueue』详尽总结

本文首发于我的个人博客:『不羁阁』 文章链接:传送门 本文用来介绍 iOS 多线程中 NSOperation、NSOperationQueue 的相关知识以及使用方法。 通过本文,您将了解到: NSOperation、NSOperationQueue 简介、操作和操作队列、使用步骤和基本使用方法、控制串行/并发执行、NSOperation 操作依赖和优先级、线程间的通信、线程同步和线程...

weixin_34295316的博客 431

从X86到ARM:将VINS-Fusion-GPU和ego-planner迁移到Jetson Orin-NX时,我踩过的那些‘环境差异’坑

本文详细介绍了将VINS-Fusion-GPU和ego-planner从X86平台迁移到Jetson Orin-NX(ARM架构)时遇到的环境差异问题及解决方案。内容涵盖ARM与X86的架构差异、依赖管理、性能调优和硬件接口适配,特别强调了CUDA在ARM平台上的优化配置和内存访问技巧,帮助开发者高效完成跨平台迁移。

weixin_42647395的博客 119

RxSwift调度者scheduler

RxSwift的核心非常简单,无非就是以下四点: 可观察序列 Observalbe 观察者 Observer 调度者 Scheduler 销毁者 Dispose 可观察序列、观察者,在《RxSwift核心源码探索》中有讲,下面就来看看调度者Scheduler具体做了哪些事情。调度者scheduler主要用于控制任务在哪个线程或队列运行,而scheduler是对GCD的封装,GCD我们很熟悉,通...

yahibo的博客 725

IFIX数据库Datebase当前值问号

IFIX数据库Datebase当前值问号,已解决,亲测有效 在OPC PowerTool有数据的情况下,IFIX数据库Datebase当前值显示???? 问题分析及解决方法 我的IFIX5.8版本,其它版本可参考 打开IFIX工作台:应用程序–任务控制–I/O驱动–OPC Client;查看OPC驱动是否被禁用,点击启动,变成激活状态即可;若点击启动无法激活OPC驱动,需要重新安装OPC驱动,方法如下: 下载I/O Driver文件 下载链接:https://download.youkuaiyun.com/down

Ron_Tso的博客 2759

车辆动力学从入门到进阶之路(传统篇)

新手如何入门车辆动力学开发领域,本文为您引路!

CrazyRabbit的博客 1万+

NSOperationQueue队列的特点

 //可以在队列中直接执行操作,而不依赖于NSOperation对象 - (void)addOperationWithBlock:(void (^)(void))block NS_AVAILABLE(10_6, 4_0); 操作只要被添加到队列: 1就会立即被执行,并且会新开一个线程 2不需要调用操作的start方法 3把操作添加到队列后,会自动对NSOperation做一

yangtongwang123456的专栏 794

大疆上云API-1.10.0版本-设备位置数据实时处理与WebSocket推送实战解析

本文深入解析了大疆上云API 1.10.0版本中设备位置数据的实时处理与推送全链路。通过剖析源码,详细阐述了从MQTT接收OSD数据、Spring Integration路由分发、业务逻辑处理到WebSocket实时推送至前端地图的核心流程,并提供了实战优化与避坑指南,帮助开发者构建高可靠的无人机实时定位系统。

weixin_29291863的博客 412

多线程之NSOperation

与GCD一样,也是我们日常开发中经常用到的多线程技术。本文将会介绍的基本使用、添加依赖、自定义。

weixin_61196797的博客 529

Zemax热分析实战:5分钟搞定双胶合透镜温度漂移优化(附操作数详解)

本文详细解析了使用Zemax进行光学系统热分析的全流程,以双胶合透镜为例,重点阐述了如何通过多重结构编辑器模拟温度变化,并利用关键操作数优化系统以抵抗温度漂移。文章提供了从基础设置到高级优化的实战技巧,帮助工程师快速掌握无热化设计方法,确保系统在宽温范围内保持稳定成像性能。

n4o5p6q7r的博客 396

RT-DETR改进策略【小目标改进】| Shape-NWD:融合改进,结合Shape-IoU和NWD 更好地适应小目标特性

Bw−wgt2h−hgt2weight2Bweight2w−wgt​2h−hgt​2​其中weight2weight = 2weight2。

Limiiiing的博客 1543

NSOperation(线程)

简介 NSOperation作用 NSOperation和NSOperationQueue也能实现多线程编程 NSOperation和NSOperationQueue实现多线程的具体步骤 先将需要执行的操作封装到一个NSOperation对象中 然后将NSOperation对象添加到NSOperationQueue中 将取出的NSOperation封装的操作放到一条新线程中执行 NSOpera...

weixin_44729579的博客 2829

2024届数字IC秋招-华为机试-数字芯片-笔试真题和答案(三)(含2022年和2023年)

此部分包含华为机试真题,方向是数字芯片,内容详细包括设计、验证、后端等,大部分题目给出参考答案。华为机试都是从题库里抽题目,所以这些题目还是很有参考性的,甚至是完全一样,可以搜到的。(题目内容较多,将分开编写几个文章)A.错误B.正确参考答案:BA.getB.try_getC.peekD.put参考答案:B。

qq_42135020的博客 1913

iOS 多线程编程技术--NSThread、Cocoa NSOperation、GCD

多线程篇(一)以下是对多线程的一些理解,如果有失偏颇之处,还望各位大神指出.话不多说,直接进入!1.什么是进程?我们手机里面每一个应用程序称一个进程.每个进程都至少会有一个主线程(main),需要时可以创建多个线程. 2.线程?线程是程序中一个单一的顺序控制流程,单个进程中可以有多个线程来完成不同的任务.(注:程序启动后,系统就会创建一个主线程(main),所有的UI控件都必须在主线程创建,因此也...

MyHaloJ 801

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

线程池NSoperationQueue和GCD比较

直接alloc创建的线程都是需要手动启动并且都是同步的、不用 分类: Object-C 2013-10-12 17:19 2296人阅读 评论(0) 收藏 举报 GCD是基于c的底层api,NSOperation属于object-c类。ios 首先引入的是NSOperation,IOS4之后引入了GCD和NSOperationQueue并且其内部是用gcd实现的。

z997756128的专栏 1427

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

NSOperationQueue 线程池的使用

#import "ViewController.h" @interface ViewController () @property(nonatomic,retain)NSOperationQueue *queue; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; //

FIGHTING的专栏 522

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

多线程编程3 - NSOperationQueue

一、简介 一个NSOperation对象可以通过调用start方法来执行任务,默认是同步执行的。也可以将NSOperation添加到一个NSOperationQueue(操作队列)中去执行,而且是异步执行的。 创建一个操作队列: NSOperationQueue *queue = [[NSOperationQueue alloc] init]; 二、添加NSOperation到NSOp

M了个J 7万+

NSOperationQueue和NSOperation的使用方法

Cpp代码 首先是建立NSOperationQueue和NSOperations。NSOperationQueue会建立一个线程管理器,每个加入到线程operation会有序的执行。  NSOperationQueue *queue = [NSOperationQueue new];  NSInvocationOperation *operation = [[NSInvocation

进阶码农的专栏 937

iOS 开发 多线程详解之NSOperation实现多线程

NSOperation简介@interface NSOperation : NSObject 1.他是一个抽象类,无法直接使用.但是我们可以使用它的子类.作为父类约束子类共有的属性和方法2.子类 - 操作默认是异步的. NSBlockOperation NSInvocationOperation 自定义NSOperation3.队列 - 默认是并发的. @interface NSOperation...

Mr_tangIT的博客 693

多线程之NSOperation和NSOperationQueue

基本概念 1: NSOperation和NSOperationQueue的基本知识点:       NSOperationQueue:代表一个 FIFO 的列队,它负责管理系统提交的多个 NSOperation,NSOperationQueue底层维护一个线性池,会按照顺序启动线程来执行提交给该列队的NSOperation任务.  NSOperation:代表一个多线程任务.NSOpe

欢迎来到Jack的程序世界 1140

iOS多线程总结(3)——NSOperation与NSOperationQueue的使用

本篇是多线程总结的第三篇,关于多线程的概念和NSThread的使用写在第一篇,《iOS多线程总结(1)——多线程相关概念及NSObject/NSThread的使用 》,第二篇《iOS多线程总结(2)——GCD》主要讲解GCD的使用,本编是线程实现总结的最后一篇,主要讲解NSOperation的使用。 一. NSOperation 在MacOSXv10.6和iOS4之前,NSOperati

诠释完美 3982

多线程(三):NSOperation,NSOperationQueue,队列的最大并发数,队列的取消暂停和恢复,NSOperation操作依赖和监听,NSOperation线程间通信

NSOperation NSOperation的作用 配合使用NSOperation和NSOperationQueue也能实现多线程编程 NSOperation和NSOperationQueue实现多线程的具体步骤 1)先将需要执行的操作封装到一个NSOperation对象中 2)然后将NSOperation对象添加到NSOperationQueu...

weixin_42433480的博客 1176

多线程:Operation和OperationQueue

多线程:实现方式Operation和OperationQueue Operation 生命周期 //都有共同特点,只读属性。 //是否准备 open var isReady: Bool { get } //是否执行 open var isExecuting: Bool { get } //是否取消 open var isCancelled: Bool { get } //是否完成 open v...

weixin_34302561的博客 355

NSOprationQueue 与 GCD 的区别与选用

GCD 技术是一个轻量的,底层实现隐藏的神奇技术,我们能够通过GCD和block轻松实现多线程编程,有时候,GCD相比其他系统提供的多线程方法更加有效,当然,有时候GCD不是最佳选择,另一个多线程编程的技术 NSOprationQueue 让我们能够将后台线程以队列方式依序执行,并提供更多操作的入口,这和 GCD 的实现有些类似。 这种类似不是一个巧合,在早期,MacOX 与 iOS 的程

ifwang之路 805

NSOperationQueue—高级功能

@interface ViewController () @property (nonatomic, strong) NSOperationQueue *opQueue; @end @implementation ViewController - (NSOperationQueue *)opQueue { if (_opQueue == nil) { _opQueue

TogeWu的博客 555

iOS多线程编程之NSOperation和NSOperationQueue的使用

(一)队列里可以加入很多个NSOperation, 可以把NSOperationQueue看作一个线程池,可往线程池中添加操作(NSOperation)到队列中。线程池中的线程可看作消费者,从队列中取走操作,并执行它。 (二)队列类型       1、主队列:添加到主队列的操作,都会放到主线程中执行。 [[NSOperationQueue mainQueue] addOperationWit

aiyang10的博客 1495
上一篇: 工作经历
下一篇: ios 调用webservice整理 + 个人针对补充
Kevin_WuJ
博客等级 码龄15年 4粉丝 10原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值