2014-06-11 2 views
0

주석을위한 제목 및 부제목과 함께 여러 GeoPoint를 얻기 위해 쿼리를 수행하고 있습니다. 쿼리는 블록의 구문 분석에서 데이터를 다운로드하고 self.locations를 기록 할 수 있습니다. 그러나, viewDidLoad에 self.locations를 기록/사용하려고하면 null이 반환됩니다. 내가 여기서 무엇을 놓치고 있니?여러 GeoPoint를 구문 분석에서 mapView에 추가하려고 시도했습니다.

#import <UIKit/UIKit.h> 
#import <MapKit/MapKit.h> 
#import <CoreLocation/CoreLocation.h> 
#import <Parse/Parse.h> 

@interface PeopleMoverMap : UIViewController <MKMapViewDelegate, CLLocationManagerDelegate> 

@property (nonatomic) double userLat; 
@property (nonatomic) double userLong; 
@property (nonatomic) NSArray *locations; 
@property (nonatomic) CLLocationManager *locationManager; 
@property (nonatomic) NSMutableArray *lats; 
@property (nonatomic) NSMutableArray *lngs; 

@property (strong, nonatomic) IBOutlet MKMapView *mapView; 

-(void)retrieveLocations; 

@end 

하는 .m 파일 :

#import "PeopleMoverMap.h" 
#import "MapAnnotation.h" 

@interface PeopleMoverMap() 

@end 

@implementation PeopleMoverMap 


- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    [self performSelector:@selector(retrieveLocations)]; 

    self.mapView.delegate = self; 

    self.locationManager = [[CLLocationManager alloc] init]; 
    self.locationManager.delegate = self; 
    self.locationManager.distanceFilter = kCLDistanceFilterNone; 
    self.locationManager.desiredAccuracy = kCLLocationAccuracyBest; 
    [self.locationManager startUpdatingLocation]; 



    // Add multiple pins 


    for (NSDictionary *location in self.locations) { 
     PFGeoPoint *tempGeo = location[@"GeoPoint"]; 

     CLLocationCoordinate2D annotationCoordinate = CLLocationCoordinate2DMake(tempGeo.latitude, tempGeo.longitude); 
     MapAnnotation *annotation = [[MapAnnotation alloc] init]; 
     annotation.coordinate = annotationCoordinate; 
//  annotation.title = location[@"Name"]; 
//  annotation.subtitle = location[@"Place"]; 
     [self.mapView addAnnotation:annotation]; 

    } 

    // Get user coordinates 
    self.userLat = self.locationManager.location.coordinate.latitude; 
    self.userLong = self.locationManager.location.coordinate.longitude; 
    NSLog(@"%f:%f", self.userLat, self.userLong); 

    // Initialize and set arrays 
    self.lats = [[NSMutableArray alloc] init]; 
    self.lngs = [[NSMutableArray alloc] init]; 

    [self.lats addObject:[NSNumber numberWithDouble:self.userLat]]; 
    [self.lngs addObject:[NSNumber numberWithDouble:self.userLong]]; 

    for (NSDictionary *dict in self.locations) { 
     PFGeoPoint *tempGeo = dict[@"GeoPoint"]; 
     [self.lats addObject:[NSNumber numberWithDouble:tempGeo.latitude]]; 
     [self.lngs addObject:[NSNumber numberWithDouble:tempGeo.longitude]]; 
    } 

    // Sort numbers in arrays 
    [self.lats sortUsingSelector:@selector(compare:)]; 
    [self.lngs sortUsingSelector:@selector(compare:)]; 

    // Get smalles/biggest coordinates 
    double smallestLat = [self.lats[0] doubleValue]; 
    double smallestLng = [self.lngs[0] doubleValue]; 
    double biggestLat = [[self.lats lastObject] doubleValue]; 
    double biggestLng = [[self.lngs lastObject] doubleValue]; 

    // Get Center Point and Span 
    CLLocationCoordinate2D annotationsCenter = CLLocationCoordinate2DMake((biggestLat + smallestLat)/2, (biggestLng + smallestLng)/2); 
    MKCoordinateSpan annotationsSpan = MKCoordinateSpanMake((biggestLat - smallestLat) * 1.75, (biggestLng - smallestLng) * 1.75); 

    // Create and set Region 
    MKCoordinateRegion region = MKCoordinateRegionMake(annotationsCenter, annotationsSpan); 
    [self.mapView setRegion:region]; 
} 

-(void)retrieveLocations 
{ 
    PFQuery *retrievePMLocations = [PFQuery queryWithClassName:@"peopleMoverLocations"]; 
    [retrievePMLocations orderByAscending:@"Name"]; 
    [retrievePMLocations findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) { 
     if (!error) { 
      self.locations = [[NSArray alloc] initWithArray:objects]; 
     } 
    }]; 
} 

@end 

답변

0

아마 당신은 findObjectsInBackgroundWithTarget를 사용한다 : 대신 선택 방법

다음은

.H 파일 내 코드입니다. selector 메서드에서 결과를 배열에 할당하고 코드를 이동하여 코드를 추가합니다. 지금은 retrieveLocations의 코드가 블록에서 실행 되더라도 나머지 ViewDidLoad 코드는 블록 완료 후 즉시 호출됩니다.

관련 질문 : findObjectsInBackgroundWithBlock: gets data from Parse, but data only exists inside the block

0

그것은 코드가 어떻게 작동하는지 비동기 이해의 문제이다.

retrieveLocations 메서드를 호출하는 것은 달걀을 퍼팅하는 것과 같습니다. 조리를 시작한 다음 다음 단계로 넘어갑니다.

달걀을 요리하기를 기다리지 않고 바로 사용하려고하면 빨리 지저분해질 것입니다. 코드와 동일합니다 ... 코드에 따라 운이 좋을 수도 있습니다. 다른 코드가 적중 될 때까지 가끔 "요리"(비동기 코드 실행이 끝났습니다)가 완료되었지만 제대로 수행하는 것이 훨씬 낫습니다.

경우에 따라 비동기 프로세스를 시작하고 나머지 UI를 "로드 중 ..."애니메이션 또는 이와 동등한 것으로 준비하십시오. UI 업데이트를 트리거하는 나머지 코드를 비동기 코드의 완료 블록으로 이동하십시오.이 코드는 실제로 데이터를 가져온 후에 만 ​​실행됩니다.

관련 문제