所以我遇到一个问题,我的代码中的变量在设置为非null值后变为null。变量在此处设置:
MKLocalSearchCompletionHandler completionHandler = ^(MKLocalSearchResponse *response, NSError *error) {
self.places = [response mapItems];
};
当我在这个代码片段外面调用self.places时,self.places为null。有什么建议吗?
这是班级(我为了简洁起见了一些方法):
#import "AddFenceController.h"
#import "PlaceAnnotation.h"
@interface AddFenceController () <UISearchBarDelegate, UISearchControllerDelegate, CLLocationManagerDelegate, MKMapViewDelegate>
@property (nonatomic, strong) CLLocationManager *locationManager;
@property (nonatomic, strong) NSMutableArray *locations;
@property (nonatomic, strong) UISearchController *searchController;
@property (nonatomic, strong) MKLocalSearchRequest *localSearchRequest;
@property (nonatomic, strong) MKLocalSearch *localSearch;
@property CLLocationCoordinate2D coords;
@property (nonatomic, strong) PlaceAnnotation *annotation;
@property (nonatomic, strong) NSArray *places;
@end
@implementation AddFenceController {
}
@synthesize latitude;
@synthesize longitude;
@synthesize region;
@synthesize radius;
@synthesize geofence;
@synthesize places;
- (void)viewDidLoad {
[self.ibSearchBar setDelegate:self];
self.latitude = [self.geofence latitude];
self.longitude = [self.geofence longitude];
self.radius = [self.geofence radius];
}
- (void)startSearch:(NSString *)searchString
{
if (self.localSearch.searching)
{
[self.localSearch cancel];
}
MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc] init];
request.naturalLanguageQuery = searchString;
MKLocalSearchCompletionHandler completionHandler = ^(MKLocalSearchResponse *response, NSError *error)
{
if (error != nil)
{
NSString *errorStr = [[error userInfo] valueForKey:NSLocalizedDescriptionKey];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Could not find places"
message:errorStr
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
}
else
{
self.places = [response mapItems];
}
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
};
if (self.localSearch != nil)
{
self.localSearch = nil;
}
self.localSearch = [[MKLocalSearch alloc] initWithRequest:request];
[self.localSearch startWithCompletionHandler:completionHandler];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
self.region = [self setUpGeofence:self.geofence.latitude.doubleValue:self.geofence.longitude.doubleValue];
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
[searchBar resignFirstResponder];
[self startSearch:self.ibSearchBar.text];
MKMapItem *mapItem = [self.places objectAtIndex:0];
self.latitude = [NSNumber numberWithDouble:mapItem.placemark.coordinate.latitude];
self.longitude = [NSNumber numberWithDouble:mapItem.placemark.coordinate.longitude];
[self.ibMapView setUserTrackingMode:MKUserTrackingModeNone];
....
}
....
@end
答案 0 :(得分:1)
我建议您在致电[response mapItems]
之前立即记录self.places
和self.places = [response mapItems];
。这可能会对情况有所了解:
NSLog(@"self.places is: %@", self.places);
NSLog(@"map items is: %@", [response mapItems]);
答案 1 :(得分:1)
程序流程存在问题:致电时
[self startSearch:self.ibSearchBar.text];
你开始搜索,然后马上回来。在下一个语句中访问self.places
为时尚早,即此处
MKMapItem *mapItem = [self.places objectAtIndex:0];
因为搜索没有机会返回!
处理此问题的正确方法是在您的类中添加另一个处理搜索完成的方法,并在设置self.places
后调用它:
// Make this change in your asynchronous handler:
if (error != nil) {
....
[alert show];
} else {
self.places = [response mapItems];
// Add this line
[self searchBarSearchCompleted];
}
....
// Add this method to your class
- (void)searchBarSearchCompleted {
MKMapItem *mapItem = [self.places objectAtIndex:0];
self.latitude = [NSNumber numberWithDouble:mapItem.placemark.coordinate.latitude];
self.longitude = [NSNumber numberWithDouble:mapItem.placemark.coordinate.longitude];
[self.ibMapView setUserTrackingMode:MKUserTrackingModeNone];
....
}
这有效地将您的searchBarSearchButtonClicked:
方法拆分为&#34;之前&#34; &#34;&#34;&#34;&#34;部分。 &#34;之前&#34;部分保持不变 - 它告诉startSearch:
启动搜索。
places
之外的searchBarSearchCompleted
,则可以完全取消该变量,并将该数组作为参数传递。