ios – 管理一堆具有依赖关系的NSOperation

ios – 管理一堆具有依赖关系的NSOperation,第1张

概述我正在开发一个创建内容并将其发送到现有后端的应用程序.内容是标题,图片和位置.没有什么花哨 后台有点复杂,所以这里是我要做的: >让用户拍照,输入标题并授权地图使用其位置 >为帖子生成一个唯一的标识符 >在后台创建帖子 >上传图片 >刷新UI 我使用了几个NSOperation子类来实现这个工作,但我不为我的代码感到骄傲,这里是一个例子. NSOperation *process = [NSBlo @H_502_0@我正在开发一个创建内容并将其发送到现有后端的应用程序.内容是标题,图片和位置.没有什么花哨

后台有点复杂,所以这里是我要做的:

>让用户拍照,输入标题并授权地图使用其位置
>为帖子生成一个唯一的标识符
>在后台创建帖子
>上传图片
>刷新UI

我使用了几个NSOperation子类来实现这个工作,但我不为我的代码感到骄傲,这里是一个例子.

NSOperation *process = [NSBlockOperation blockOperationWithBlock:^{    // Process image before upload}];NSOperation *filename = [[NSInvocationoperation alloc] initWithTarget: self selector: @selector(generatefilename) object: nil];NSOperation *generateEntry = [[NSInvocationoperation alloc] initWithTarget: self selector: @selector(createEntry) object: nil];NSOperation *uploadImage = [[NSInvocationoperation alloc] initWithTarget: self selector: @selector(uploadImagetoCreatedEntry) object: nil];NSOperation *refresh = [NSBlockOperation blockOperationWithBlock:^{    // Update UI    [SVProgressHUD showSuccessWithStatus: NSLocalizedString(@"Success!",@"Success HUD message")];}];[refresh addDependency: uploadImage];[uploadImage addDependency: generateEntry];[generateEntry addDependency: filename];[generateEntry addDependency: process];[[NSOperationQueue mainQueue] addOperation: refresh];[_queue addOperations: @[uploadImage,generateEntry,filename,process] waitUntilFinished: NO];

以下是我不喜欢的东西:

>在我的createEntry中:例如,我将生成的文件名存储在一个属性中,它与我的类的全局范围
>在uploadImagetoCreatedEntry:方法中,我使用dispatch_async dispatch_get_main_queue()来更新我的HUD中的消息
>等

你如何管理这样的工作流?我想避免嵌入多个完成块,我觉得NSOperation真的是要走的路,但我也觉得在某个地方有更好的实现.

谢谢!

解决方法 您可以使用 ReactiveCocoa
完成这个很容易.其中一个大目标就是制造这样的一个
构成微不足道

如果您以前没有听说过ReactiveCocoa,或者不熟悉它,请检查
出Introduction
为了快速解释.

我将避免在这里重复整个框架概述,但足以说出来
RAC实际上提供了一个承诺/期货的超集.它允许你组合和
完全不同起源的转换事件(UI,网络,数据库,KVO,
通知等),这是非常强大的.

要开始RACify这个代码,我们可以做的第一个也是最简单的事情
这些单独的 *** 作变成方法,并确保每个 *** 作都返回
RAC信号.这并不是绝对必要的(它们都可以在其中定义
一个范围),但它使代码更加模块化和可读性.

例如,让我们创建一个对应的进程和对应的信号
generatefilename:

- (RACSignal *)processImage:(UIImage *)image {    return [RACSignal startEagerlyWithScheduler:[RACScheduler scheduler] block:^(ID<RACSubscriber> subscriber) {        // Process image before upload        UIImage *processedImage = …;        [subscriber sendNext:processedImage];        [subscriber sendCompleted];    }];}- (RACSignal *)generatefilename {    return [RACSignal startEagerlyWithScheduler:[RACScheduler scheduler] block:^(ID<RACSubscriber> subscriber) {        Nsstring *filename = [self generatefilename];        [subscriber sendNext:filename];        [subscriber sendCompleted];    }];}

其他 *** 作(createEntry和uploadImagetoCreatedEntry)将非常相似.

一旦我们有了这些,就很容易组成他们并表达他们的意思
依赖关系(虽然注释使它看起来有点密集):

[[[[[[self    generatefilename]    flattenMap:^(Nsstring *filename) {        // Returns a signal representing the entry creation.        // We assume that this will eventually send an `Entry` object.        return [self createEntryWithfilename:filename];    }]    // Combine the value with that returned by `-processImage:`.    zipwith:[self processImage:startingImage]]    flattenMap:^(RACTuple *entryAndImage) {        // Here,we unpack the zipped values then return a single object,// which is just a signal representing the upload.        return [self uploadImage:entryAndImage[1] toCreatedEntry:entryAndImage[0]];    }]    // Make sure that the next code runs on the main thread.    deliverOn:RACScheduler.mainThreadScheduler]    subscribeError:^(NSError *error) {        // Any errors will trickle down into this block,where we can        // display them.        [self presentError:error];    } completed:^{        // Update UI        [SVProgressHUD showSuccessWithStatus: NSLocalizedString(@"Success!",@"Success HUD message")];    }];

请注意,我重命名了一些方法,以便他们可以接受输入
他们的依赖,给我们一个更自然的方式来从一个价值观
*** 作到下一个

这里有很大的优势:

>您可以自上而下阅读,所以很容易理解这个顺序
事情发生在哪里,依赖性在何处.
>在不同的线程之间移动工作非常容易,如下所示
使用-deliverOn :.
>任何这些方法发送的任何错误将自动取消所有这些
其余的工作,最终达到subscribeError:block容易
处理.
>你也可以用其他事件流(即不只是)来组合
*** 作).例如,您可以将其设置为仅在UI时触发
信号(如按钮点击)触发.

ReactiveCocoa是一个巨大的框架,不幸的是很难蒸馏
优点下降到一个小的代码示例.我强烈建议您查看
when to use ReactiveCocoa的例子了解更多关于如何帮助.

总结

以上是内存溢出为你收集整理的ios – 管理一堆具有依赖关系的NSOperation全部内容,希望文章能够帮你解决ios – 管理一堆具有依赖关系的NSOperation所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/web/1111120.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-29
下一篇 2022-05-29

发表评论

登录后才能评论

评论列表(0条)

保存