我对Objective-C和Swift知之甚少,但在花了几个小时编写了一个本地插件,使用iOS中的后台线程收集指南针数据后,下面是到目前为止的插件
// MyPlugin.m
extern "C" {
#import <CoreLocation/CoreLocation.h>
#import "MyPlugin.h"
@implementation MyPlugin
NSThread *_magneticHeadThread;
BOOL _shouldStop;
NSMutableArray *readings;
- (void)startBackgroundThread {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
// Put your code here that should run in the background when the app enters background.
NSLog(@"Background thread started!");
readings = [NSMutableArray array];
_magneticHeadThread = [[NSThread alloc] initWithTarget:self selector:@selector(retrieveMagneticHeadPosition) object:nil];
[_magneticHeadThread start];
});
}
- (void)applicationDidEnterBackground:(NSNotification *)notification {
_shouldStop = NO;
[self startBackgroundThread];
}
- (void)applicationWillEnterForeground:(NSNotification *)notification {
_shouldStop = YES;
[_magneticHeadThread cancel];
NSLog(@"Magnetic head position: %lu", [readings count]);
}
+ (instancetype)sharedInstance {
static MyPlugin *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[MyPlugin alloc] init];
});
return sharedInstance;
}
- (void)retrieveMagneticHeadPosition {
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
locationManager.headingFilter = kCLHeadingFilterNone;
[locationManager startUpdatingHeading];
int c = 0;
while (!_shouldStop) {
NSLog(@"Magnetic head position: %i", c);
c++;
[readings addObject:@(locationManager.heading.magneticHeading)];
[NSThread sleepForTimeInterval:0.1];
}
[locationManager stopUpdatingHeading];
}
@end
void UnityMyPlugin_StartBackgroundThread() {
[[NSNotificationCenter defaultCenter] addObserver:[MyPlugin sharedInstance] selector:@selector(applicationDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:[MyPlugin sharedInstance] selector:@selector(applicationWillEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil];
}
}
它在Start函数的MonoBehaviour中被调用:
void Start()
{
Application.runInBackground = true;
#if UNITY_IPHONE && !UNITY_EDITOR
UnityMyPlugin_StartBackgroundThread();
#endif
}
我已经读到dispatch_async期望在固定时间内完成,但我没有找到任何关于无限线程的线索,也没有关于服务的信息来请求信息,如magneticHeading,你能告诉我在哪里检查或向谁询问解决方案吗?我在寻找任何可能的东西吗?我在这段代码中做了什么不好的选择吗?谢谢
这个解决方案,它的编译和工作~ 2s之前被取消的SO,但我正在寻找一个线程,收集数据的一个较长的时间或服务,要求一系列的时间戳,并获得信息。
1条答案
按热度按时间yc0p9oo01#
你在这里的方法是错误的。你没有在线程上不断地轮询CLLocationManager。你启动一次CLLocationManager,让它运行你想要的信息。应用程序将定期接收更新。不需要任何类型的线程,也绝对不需要轮询循环。
有关获取权限和其他所需设置,请参阅Configuring your app to use location services。有关在后台阅读位置信息的更多详细信息,请参阅Handling location updates in the background。您的应用不会在后台持续轮询信息。操作系统将在事件可用时交付事件,并可能在需要时启动您的应用。
虽然当前的问题不需要线程或队列,但值得注意的是,DISPATCH_QUEUE_PRIORITY_BACKGROUND是一个非常低优先级的队列,当应用程序处于后台时,它通常根本不会运行。(我从未真正想过这个名字有多反直觉。)即使在应用程序处于后台时应该运行此代码的情况下,您也不希望使用该优先级。
一般来说,如果你发现自己在使用
sleepForTimeInterval:
,你可能做错了什么,它有时候是正确的工具,但是非常罕见,特别是如果你是一个初学者。