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

Ios 在单独的线程中循环位置数组,ios,objective-c,arrays,multithreading,Ios,Objective C,Arrays,Multithreading,我正在为iPhone开发一个应用程序,并跟踪用户的当前位置。当didupdateLocationsdelegate方法实际执行时,我想测试NSArray中的位置是否在预定义的数组中,该数组是否包含其他位置,您可能会随着时间的推移而增长 我正在这个方法中运行一个for循环来测试我自己的位置数组,但是我想把它转移到一个单独的线程。因此,如果我自己的多个位置的数组增长到很大数量,for循环不会冻结我的UI。 我试过这样做,但结果不理想。我知道位置跟踪肯定是在一个单独的线程中进行的。但是,那些didup

我正在为iPhone开发一个应用程序,并跟踪用户的当前位置。当
didupdateLocations
delegate方法实际执行时,我想测试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];
     });



}
-(无效)locationManager:(CLLocationManager*)manager
didUpdateLocations:(NSArray*)此位置{
调度队列=调度获取全局队列(调度队列优先级默认为0);
//获取位置数组中的最后一个对象
CLLocation*location=[thisLocation lastObject];
调度异步(队列^{
[自检MyArray:位置];
});
}
-(void)checkmyArray:(CLLocation*)工作位置{
NSLog(“声音警报”);
int alarm_on_c=0;
NSU整数tmp_计数=[theData.LocationsObjectArray计数];
布尔报警;
NSMutableDictionary*tempObject;
CLLocationDistance距离=0.0;
对于(int i=0;i如果(距离如果可以避免的话,在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
        }
    }
}
-(无效)检查位置开始:(NSNumber)开始
{
NSInteger s=(开始)?[start intValue]:0;
对于(i=s;i太多){
[自执行选择器:@选择器(checkLocationsStartingAt:)
withObject:@(i)
后延迟:0.001];
返回;
}否则{
//检查i处的元素
}
}
}

请参阅:

您正在检查一个位置与其他位置的数组。 当距离某个位置超过350米时,将显示警报。 您可能位于列表中许多项目的350米范围内。 您没有阻止多个警报的代码

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

你有几个选择。其中一个可能比其他的更适合你的需要。可能是我没有列出的一个

  • 您可以重复使用单个
    UIAlertView
    实例并检查
    visible
    属性。如果它已可见,则不执行任何操作
  • 一旦你被“击中”,你就可以打破这个循环
    你得到了什么不希望得到的结果?你想得到什么?警报执行多次。我只想在目标在350米以内时显示警报。每次位置更新时,代码都会执行。这可能比你希望执行代码的频率更高。听起来你可能需要区域监视:也许你应该在位置管理器上设置一个距离过滤器:这个?我猜你的意思是selfAndrew,我只是有点困惑,太多的人是从哪里来的?对不起,noob的问题。在iOS中使用线程没有什么错。这是鼓励的,在很多情况下都会非常有益,特别是如果你使用像GCD这样的东西(比如@Miguel)@Miguel您可以将其定义为程序中其他地方的常量(例如,*.m文件的顶部)@vikingosegundoops…最近使用了大量JavaScript…:-)