通过多线程分配 CoreLocation 和 CoreMotion 更新的最佳设计?

Posted

技术标签:

【中文标题】通过多线程分配 CoreLocation 和 CoreMotion 更新的最佳设计?【英文标题】:Best design for assigning CoreLocation & CoreMotion updates through multithreading? 【发布时间】:2012-08-12 00:10:40 【问题描述】:

我有一个Game 类,它有一个-(void) play 方法,当用户单击设备上的“播放”按钮时将执行该方法。

-(void) play 方法中,我有一个while 循环,它将重复执行,直到用户单击退出按钮。这个while循环基本上是我代码的核心,所有必要的方法都被调用,事情发生,对象交互等等。

我还有一个 User 类(以及其他类..),我在我的 Game 类的 -(void) play 方法中创建了一个 User* player 实例来存储一些值,并让这些值在运行期间与其他事物交互游戏..

现在我需要知道(在游戏中的任何时候......)设备与磁北的偏差以及用户在设备上锻炼的加速度

我已经编写了代码,一切都工作正常。但是,作为编程新手,我对代码的整体设计有一些疑问,我认为这是一团糟,尤其是在使用 CoreLocation 和 CoreMotion 框架时 ..

Game 类的-(void) play 方法(基本上是我的“main”方法)在一个单独的线程上执行,就像[game performSelectorInBackground:@selector(play) withObject:nil]; 一样,这是正确的做法吗?

但是,我从 -(void) play 方法内部初始化 CoreMotion Acceleration 更新,就像在 [motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue mainQueue]withHandler:^(CMDeviceMotion *motion, NSError *error)... 中一样,这意味着更新将存储在主队列中,而初始化这些更新的方法是从方法内部执行的 (-(void) play)在单独的线程上运行。这有意义吗?

当我初始化我的 Game 类的实例时,我也会初始化 CoreLocation 更新。更诡异?

我的观点是这样的。鉴于我将测量用户在设备上锻炼的加速度以及他/她给设备的方向(度数),我想将所有这些都封装在我的 User 类中,并使用 [player getMyDegrees]; 和 @987654332 之类的方法@这不是设计的正确方式吗?我应该在哪里初始化这些更新?从内部哪个特定的类方法?一切都应该运行在同一个主线程还是同一个单独的线程或不同的单独线程上?我很困惑。。

【问题讨论】:

【参考方案1】:

线程是一个复杂的问题,正如您所看到的那样。

Game类的-(void) play方法(基本上是我的 "main" 方法)在一个单独的线程上执行,如 [game performSelectorInBackground:@selector(play) withObject:nil];这是 正确的做法?

这取决于。您在 -play 方法中所做的任何工作绝对必须从主线程中移除(即疯狂的数字运算、服务器请求、加载纹理等)以使 UI 更具响应性?这确实是在 ios 上将方法分派到后台的唯一原因,是为了维护响应式 UI,因为 UIKit 类不仅是线程不安全的,而且如果您尝试这样做,它们会全心全意地直接跳下悬崖并带走您的应用程序在后台做任何事情。

但是,我从内部初始化 CoreMotion Acceleration 更新 -(void) play method ... 这意味着... 这些更新是从在单独线程上运行的方法(-(void) play) 内部执行的。做 这有意义吗?

好吧,这又取决于这里。线程化的最终目标不是让两个或更多线程尝试访问或改变另一个线程持有的一个对象,这只是一大堆问题的开始。我必须解决的一件事是,尽管documentation 中有一个非常明确和不祥的警告,但您仍在使用主队列:

因为已处理的事件可能会以很高的速度到达,使用 不推荐主操作队列。

这是您应该将其扔给后台线程的高功率计算之一的示例,这是NSOperationQueue 的强项。

我想将所有内容封装在我的 User 类中,并拥有类似的方法 [玩家getMyDegrees];和[玩家getMyAcceleration];这不是 正确的设计方式?我应该在哪里初始化那些 更新?来自哪个特定的类方法?

这取决于您在设计方面的努力程度,以及您认为什么是好的设计。好的代码通常是您可以将其交给其他程序员并让他们从您开始的地方轻松获取的代码。话虽如此,听起来您的用户类将成为 MVC 的控制器部分。如果你的课程太庞大,就把它们删掉。 Objective-c 中的类是令人惊讶的轻量级生物。即使在描述通用部分实现的多个类别中安排一个类也可以(例如 NSString 的标题)。

所有东西都应该在同一个主线程上运行还是在同一个主线程上运行? 单独的线程或不同的单独线程?我很困惑..

所有 UI 和轻量级都应该在主线程中运行(或主队列,如果你喜欢这样看的话),所有重度和线程阻塞都应该放在后台线程中。

【讨论】:

感谢您的回答 Coda,我担心我的长文本会吓跑大多数人..:) -(void) play 方法所做的工作并不复杂。它基本上反复检查加速度计和磁力计(这就是为什么一切都发生在一个while循环内)只要用户不按退出并根据它获得的值执行基本算术并发出短促的声音或它不不。但是我在一个单独的线程上执行它,因为它不断访问这些更新,担心如果我在主线程上这样做会阻塞 iOS 我知道有关 CoreMotion 更新的警告,我将尝试使用 currentQueue。有人告诉我,在使用 CoreLocation 时,我不应该使用后台线程,而是使用主线程。但是,如果我希望我的 User 类处理这些更新,我怎样才能让 coreMotion 那些在单独的线程上执行,而 Corelocation 那些在主线程上。这就是我感到困惑的地方.. 嗯,这是稳定性和准确性之间的权衡。

以上是关于通过多线程分配 CoreLocation 和 CoreMotion 更新的最佳设计?的主要内容,如果未能解决你的问题,请参考以下文章

JNI 通过多线程从 C++ 调用 Java

如何通过多线程 Java 编程最大限度地利用资源(RAM 和 CPU)?

Python通过多线程实现 `异步`

通过多线程(任务)运行方法的有效方法[重复]

如何通过多线程概念下载单个文件

C++ - 通过多线程同时播放多个哔声?