iPhone performSelectorInBackground

时间:2011-11-21 11:32:09

标签: iphone objective-c multithreading geolocation performselector

我有这个问题: 这是我的appDelegate文件的一部分,我在其中创建了一个“performSelectorInBackground”方法。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

[self addSplash];

[self getLocation];

[self performSelectorInBackground:@selector(backgroundOp) withObject:nil];

return YES;

}

首先我添加一些启动画面,我得到一个位置和调用背景方法。 这是背景方法的内容:

- (void) backgroundOp
{

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    [self createEditableCopyOfDatabaseIfNeeded];

    [self initTempData];

    [self initApp];

    [self checkDataVersion];

    } 

    [self setAppStrings];

    [self performSelectorOnMainThread:@selector(resultOp) withObject:nil waitUntilDone:YES];

    [pool release];


}

我下载了一些数据,检查数据版本,设置应用程序字符串以及调用主线程方法来创建标签栏控制器代码:

- (void) resultOp
{

    tabBarController.delegate = self;


    [self.window addSubview:tabBarController.view];
    [self addTabBarArrow];
    [self.window makeKeyAndVisible];

    [self removeSplash];

}

在这里,我创建一个标签栏控制器并删除启动画面。然后启动我的firstViewController。

问题是在我的firstViewController中我显示了当前位置,但这是错误的。有时是正确的,但往往是错误的。 哪里有问题?有没有选项如何检查后台线程是否结束?或者我的问题的其他解决方案(我只需要:show splash with activity indicator和一些消息(这些消息在方法中更改,例如init,get location等),然后我需要获取位置,remove splash和show firstController)。 ..非常感谢

编辑:以下是位置代码:

- (void) getLocation 
{


    splashScreenController.splashLabel.text = @"Localization ...";

    locationManager = [[CLLocationManager alloc] init];
    locationManager.delegate = self;
    locationManager.distanceFilter = kDistanceFilter;
    locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
    [locationManager startUpdatingLocation];



}

2 个答案:

答案 0 :(得分:0)

请注意,位置更新运行的时间越长,获得的准确性就越高。该位置的第一个“点击”并不总是最好的(大部分时间是错误的)。

也许你可以在你拥有CLLocationManager事件的地方展示你的代码。

另外,正确位置的错误位置是多少?我认为AGPS首先通过使用附近的WiFi热点快速检查其位置,然后通过使用GPS芯片获得更准确。

答案 1 :(得分:0)

无论您在哪里使用您获得的位置(我从您发布的代码中都看不到),您应该检查您正在接收的newLocation的horizo​​ntalAccuracy属性(如果高度很重要,还应检查verticalAccuracy)。你可以这样说

if(newLocation.horizontalAccuracy < 100) {
    //do something with newLocation
    //because it is accurate to 100 meters
}

如果您不进行这些类型的检查,您可以获得一些真正不准确的位置,最初距离您的实际位置最多三到四公里。

此外,使用多个线程时,数据完整性有时会成为问题。您需要确保在多种方法中不会同时访问和更改变量,或者谁知道您是否会获得正确的输出。

另外,需要注意的是,backgroundOp中调用的所有方法也将在后台执行,即使没有以这种方式显式调用它们。使用

[self performSelectorOnMainThread:foo withObject:foobar waitUntilDone:NO];

返回主线程。

编辑:

viewDidLoad {
    [super viewDidLoad];
    iterations = -5;
}

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation 
    *)newLocation fromLocation:(CLLocation *)oldLocation {
    iterations++;
    if(iterations > 0) {
        if(newLocation.horizontalAccuracy < 50) {
            //do something with location with radius of uncertainty
            //of less than 50
        }
    }