【发布时间】:2014-09-25 00:00:48
【问题描述】:
我正在为 iPhone 开发一个应用程序,我正在跟踪用户的当前位置。当didupdateLocations 委托方法实际执行时,我想测试 NSArray 中的位置是否在包含其他位置的预定义数组中,这个数组会随着时间的推移而增长。
我在这个方法中运行了一个 for 循环来测试我自己的位置数组,但我想把它移到一个单独的线程中。因此,如果我自己的具有多个位置的数组增长到大量,for 循环不会冻结我的 UI。
我已经像这样尝试过,但我得到了不希望的结果。我知道位置跟踪肯定发生在一个单独的线程中。但是那些didupdateLocations 在单独的线程上执行。 Apple 文档对此事不是很清楚。我的最终目标是与我的数组进行比较,而不是锁定 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];
});
}
【问题讨论】:
-
您得到了什么不良结果?你想得到什么?
-
警报执行多次。我只想在目标在 350 米以内时显示警报
-
每次位置更新时都会执行代码。这可能比您希望执行的代码更频繁。
-
也许你应该在位置管理器上设置一个距离过滤器:developer.apple.com/library/ios/documentation/CoreLocation/…
标签: ios objective-c arrays multithreading