我正在处理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];
});
}
答案 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
}
}
}
答案 1 :(得分:1)
您正在针对其他位置的数组检查一个位置。 您可以显示距离某个位置350米以内的时间的警报。 您可以在列表中的许多项目的350米范围内。 您没有代码可以阻止多个警报。
因此,您有时会收到很多警报。
你有几个选择。一个人可能比其他人更好地满足你的需求。可能是我没有列出的一个。
UIAlertView
实例并检查
它上面有visible
财产。如果它已经可见,则什么也不做。 BOOL
来记录你是否已经显示警报
每次再次显示警报之前,请检查BOOL
。