在单独的线程中循环的位置数组

时间:2014-08-01 18:00:19

标签: ios objective-c arrays multithreading

我正在处理iPhone的应用程序,而且我正在跟踪用户的当前位置。当didupdateLocations委托方法实际执行时,我想测试NSArray中的位置是否在包含其他位置的预定义数组中,这个数组可能会随着时间的推移而增长。

我在这个方法中运行for循环来测试我自己的位置数组,但我想把它移到一个单独的线程中。因此,如果我自己的多个位置的数组增长到很多,for循环不会冻结我的UI。 我试过这样的但是我得到了不良结果。我知道位置跟踪肯定发生在一个单独的线程中。但是那些didupdateLocations在一个单独的线程上执行。苹果医生在这件事上并不十分清楚。我的最终目标是再次与我的数组进行比较而不是锁定UI。

  - (void)locationManager:(CLLocationManager *)manager
         didUpdateLocations:(NSArray *)thisLocation {

    dispatch_queue_t queue= dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    // get the last object in the array of locations
    CLLocation* location = [thisLocation lastObject];

     dispatch_async(queue, ^{
         [self checkmyArray:location];
     });

}



 -(void)checkmyArray:(CLLocation *)workingLocation{

    NSLog(@"SoundTheAlarm");
     int alarm_on_c = 0;
     NSUInteger tmp_count = [theData.LocationsObjectArray count];
     BOOL alarm;
     NSMutableDictionary * tempObject;
     CLLocationDistance distance = 0.0;


    for (int i = 0; i < tmp_count; i++) {

        tempObject= [theData.LocationsObjectArray objectAtIndex:i];

         thisLoc = [[tempObject objectForKey:@"onoff"] isEqual:@YES];


        if (thisLoc) {


            //check if we are near that location
            double lat = [[tempObject objectForKey:@"latitude"] doubleValue];
            double lon = [[tempObject objectForKey:@"longitude"] doubleValue];

            // goal = [[CLLocation alloc] initWithLatitude:40.097771 longitude:-74.941399];
            goal = [[CLLocation alloc] initWithLatitude:lat longitude:lon];

            // check the destination between current location and goal location - in meters
            distance = [goal distanceFromLocation:workingLocation];

            NSLog(@"distance %f\n", distance);
        }


        // if distance from goal is less than 350 meters
        if (distance <= 350){

                [self scheduleNotification:[tempObject objectForKey:@"name"]];

                // turn off tracking for this location
                [tempObject setObject:@NO forKey:@"onoff"];
                [theData.LocationsObjectArray replaceObjectAtIndex:i withObject:tempObject];

                NSIndexPath *path = [NSIndexPath indexPathForRow:i inSection:0];
                ExtendedSavedCellTableViewCell *cell = (ExtendedSavedCellTableViewCell *)[self.tableView cellForRowAtIndexPath:path];
                cell.switchView.on = NO;

                // save the update to the switch to the database as well
                NSString *lat = [tempObject objectForKey:@"latitude"];

                /*check to determine if the uiswitch is turned off or on.*/

                [self fetchedResultsController:@NO lat:lat index:path];
                [self displayAlertViewForAlarm:[tempObject objectForKey:@"name"]];


}

-(void)displayAlertViewForAlarm:(NSString *)nameOfLocation{

     dispatch_async(dispatch_get_main_queue(), ^(void) {


    UIAlertView *myAlert = [[UIAlertView alloc] initWithTitle:@"Destination reached"
                                                      message:nameOfLocation
                                                     delegate:self
                                            cancelButtonTitle:@"Go Away"
                                            otherButtonTitles:@"Notify", nil];


    [myAlert show];
     });



}

2 个答案:

答案 0 :(得分:1)

如果你完全可以避免使用线程,那么在iOS中使用线程通常是一个坏主意。在你的情况下,我实现了循环的函数,它在迭代次数过多后自动弹出循环,然后调度下一个迭代块,在另一次循环中发生事件循环。换句话说,就像这样:

- (void) checkLocationsStartingAt:(NSNumber)start
{
    NSInteger s = (start) ? [start intValue] : 0;
    for (i = s; i < list.length; i++) {
        if (i > TOO_MANY) {
            [self performSelector:@selector(checkLocationsStartingAt:)
                       withObject:@(i) 
                       afterDelay:0.001];
            return;
        } else {
            // check element at i
        }
    }
}

请参阅:NSObject Reference

答案 1 :(得分:1)

您正在针对其他位置的数组检查一个位置。 您可以显示距离某个位置350米以内的时间的警报。 您可以在列表中的许多项目的350米范围内。 您没有代码可以阻止多个警报。

因此,您有时会收到很多警报。

你有几个选择。一个人可能比其他人更好地满足你的需求。可能是我没有列出的一个。

  • 您可以重复使用单个UIAlertView实例并检查 它上面有visible财产。如果它已经可见,则什么也不做。
  • 一旦你受到一次“击中”,你就可以突破循环 &LT;350米
  • 你可以坚持使用BOOL来记录你是否已经显示警报 每次再次显示警报之前,请检查BOOL