Objective-C 顺序执行两个完成块
Posted
技术标签:
【中文标题】Objective-C 顺序执行两个完成块【英文标题】:Objective-C sequentially Executing Two Completion Blocks 【发布时间】:2018-05-25 18:28:59 【问题描述】:我目前正致力于使 DJI 产品能够自主执行航点任务,改编自 DJI 教程 (https://developer.dji.com/mobile-sdk/documentation/ios-tutorials/GSDemo.html)。所以我试图将所有流程整合到一个功能中。这是我必须集成的两个完成块:
[[self missionOperator] uploadMissionWithCompletion:^(NSError * _Nullable error)
if (error)
ShowMessage(@"Upload Mission failed", error.description, @"", nil, @"OK");
else
ShowMessage(@"Upload Mission Finished", @"", @"", nil, @"OK");
];
和:
[[self missionOperator] startMissionWithCompletion:^(NSError * _Nullable error)
if (error)
ShowMessage(@"Start Mission Failed", error.description, @"", nil, @"OK");
else
ShowMessage(@"Mission Started", @"", @"", nil, @"OK");
];
为了使第二个成功运行,第一个必须首先完全执行。这似乎不是一个难题,但在尝试添加延迟或调度后我无法弄清楚。
感谢任何帮助。谢谢。
【问题讨论】:
现在的行为是什么?该信息可能会有所帮助。为什么不在第一个函数中设置一个布尔值,然后在第二个函数中检查它。 我试图用布尔值确认执行状态。但问题是,随着上传命令的执行,ShowMessage命令会立即执行,但其中的所有进程并没有立即完成。所以随着布尔值的变化,启动命令执行,程序发现因为上传没有完成,所以无法运行。 是的,在这种情况下你会想要使用异步调度队列。 为什么不同步调度,因为我需要按顺序执行?抱歉,我是这个 XD 的新手 串行队列? NSOperations 有依赖关系? 【参考方案1】:来自the iOS version of the docs you linked,-[DJIWaypointMissionOperator uploadMissionWithCompletion:]
的文档说:
如果启动成功,使用
addListenerToUploadEvent:withQueue:andBlock
接收详细进度。
所以,你会做这样的事情:
[[self missionOperator] uploadMissionWithCompletion:^(NSError * _Nullable error)
if (error)
ShowMessage(@"Upload Mission failed", error.description, @"", nil, @"OK");
else
ShowMessage(@"Upload Mission Started", @"", @"", nil, @"OK");
[[self missionOperator] addListenerToUploadEvent:self
withQueue:nil
andBlock:^(DJIWaypointMissionUploadEvent *event)
if (event.currentState == DJIWaypointMissionStateReadyToExecute)
[[self missionOperator] startMissionWithCompletion:^(NSError * _Nullable error)
if (error)
ShowMessage(@"Start Mission Failed", error.description, @"", nil, @"OK");
else
ShowMessage(@"Mission Started", @"", @"", nil, @"OK");
];
else if (event.error)
ShowMessage(@"Upload Mission failed", event.error.description, @"", nil, @"OK");
];
];
【讨论】:
如果这是两个通用的完成块,您将是正确的。但是在后台,有一个变量跟踪进程的状态。我可以访问它的值,但不知道如何更改。因此,uploadMissionWithCompletion 将该变量从“准备上传”更改为“正在上传”。当上传实际完成时,状态变为“已上传”。只有当状态变为“已上传”时,“startMissionWithCompletion”才会执行。 这是一个与此相关的页面 (developer.dji.com/api-reference/android-api/Components/Missions/…)。 那么当上传没有真正完成时,你提供给upload...
方法的完成处理程序会被调用?
是的。所以我认为我应该在某处添加延迟。但我需要确保 startMission 正在等待,uploadMission 应该继续运行直到它完全完成。
如果“上传任务完成”还没有真正完成,为什么还要记录呢?在事情完成之前调用完成处理程序是一个非常奇怪的设计。无论如何,我已经编辑了我的答案以显示替代方案。【参考方案2】:
您的代码看起来正确。我遇到了同样的问题,在我的任务完成上传后,我的missionOperator 的currentState
将恢复为DJIWaypointMissionStateReadyToUpload
而不是DJIWaypointMissionStateReadyToExecute
。该任务已通过有效性检查,但实际上由于个别航点的曲线要求无效(cornerRadiusInMeters
属性)而无效。
来自文档:
/**
* Corner radius of the waypoint. When the flight path mode is
* `DJIWaypointMissionFlightPathCurved` the flight path near a waypoint will be a
* curve (rounded corner) with radius [0.2,1000]. When there is a corner radius,
* the aircraft will never go through the waypoint. By default, the radius is 0.2
* m. If the corner is made of three adjacent waypoints (Short for A,B,C) . Then
* the radius of A(short for Ra) plus radius of B(short for Rb) must be smaller
* than the distance between A and B. The radius of the first and the last
* waypoint in a mission does not affect the flight path and it should keep the
* default value (0.2m).
*/
希望这对某人有所帮助。
【讨论】:
以上是关于Objective-C 顺序执行两个完成块的主要内容,如果未能解决你的问题,请参考以下文章
如何将 Objective-C 的完成块转换为 Swift?
IOS/Objective-C:从完成块中检索 NSArray
在swift文件中调用objective-C属性块,完成块属性变为零