2013-09-26 1 views
0

다른 많은 곳에서 사용되는 일반적인 메서드를 만들기 위해 RestKit 버전 0.20.3을 사용하고 있습니다. 문제는 "반환 위치;"때문에 해당 메서드에서 반환 된 값은 항상 nil입니다. 문은 [objectManager getObjectsAtPath ...] 메소드 (아래 코드 참조)에 대한 Success 콜백 함수보다 먼저 실행됩니다.일반 메서드 용 동기 호출 웹 API 서비스

"반환 위치"를 원합니다. 명령문은 블록 변수 "location"에 대한 WAIT가 [objectManager getObjectsAtPath ...] 메소드 내의 Success 콜백 함수의 데이터로 채워 져야 함을 나타냅니다. 어떻게해야합니까?

도움 주셔서 감사합니다. 당신은 그것을 나쁜 디자인 때문에 당신이 원하는 것을 변경해야

-(KNSunGoogleLatitudeLongitudeGeometryLocation*)getSynchronouslyLatitudeLongitudeWithAddress:(NSString*)address 
{ 
    __block KNSunGoogleLatitudeLongitudeGeometryLocation* location = [[KNSunGoogleLatitudeLongitudeGeometryLocation alloc] init]; 


    NSURL *baseURL = [NSURL URLWithString:@"http://maps.googleapis.com/maps/api"]; 
    AFHTTPClient * client = [AFHTTPClient clientWithBaseURL:baseURL]; 
    [client setDefaultHeader:@"Accept" value:RKMIMETypeJSON]; 
    RKObjectManager *objectManager = [[RKObjectManager alloc] initWithHTTPClient:client]; 


    //1. KNSunGoogleLatitudeLongitudeGeometryLocation 

    RKObjectMapping *locationMapping = [RKObjectMapping mappingForClass:[KNSunGoogleLatitudeLongitudeGeometryLocation class]]; 
    [locationMapping addAttributeMappingsFromArray:@[@"lat", @"lng"]]; 


    //2. KNSunGoogleLatitudeLongitudeGeometry 

    RKObjectMapping *geometryMapping = [RKObjectMapping mappingForClass:[KNSunGoogleLatitudeLongitudeGeometry class]]; 

    //3. KNSunGoogleLatitudeLongitude 

    RKObjectMapping *latLongMapping = [RKObjectMapping mappingForClass:[KNSunGoogleLatitudeLongitude class]]; 



    //4. property/relationship mapping 

    [geometryMapping addPropertyMapping:[RKRelationshipMapping 
             relationshipMappingFromKeyPath:@"location" 
             toKeyPath:@"location" 
             withMapping:locationMapping]]; 

    [latLongMapping addPropertyMapping:[RKRelationshipMapping 
             relationshipMappingFromKeyPath:@"geometry" 
             toKeyPath:@"geometry" 
             withMapping:geometryMapping]]; 



    // 6. response 
    RKResponseDescriptor * responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:latLongMapping 
                          method:RKRequestMethodGET 
                         pathPattern:nil 
                          keyPath:@"results" 
                         statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]; 
    // 7 
    [objectManager addResponseDescriptor:responseDescriptor]; 



    NSDictionary *queryParams; 
    queryParams = [NSDictionary dictionaryWithObjectsAndKeys:address, @"address", @"false", @"sensor", nil]; 


    // 6 

    [objectManager getObjectsAtPath:@"http://maps.googleapis.com/maps/api/geocode/json" 
         parameters:queryParams 
          success:^(RKObjectRequestOperation * operaton, RKMappingResult *mappingResult) 
    { 

      //----------- 
      NSArray* results = [mappingResult array]; 
      KNSunGoogleLatitudeLongitude* result0 = [results objectAtIndex:0]; 
      KNSunGoogleLatitudeLongitudeGeometry* geometry = result0.geometry; 

      location= geometry.location; 

      NSLog(@"lat=%@, long=%@", location.lat, location.lng); 


    } 
          failure:^(RKObjectRequestOperation * operaton, NSError * error) 
    { 
     NSLog (@"failure: operation: %@ \n\nerror: %@", operaton, error); 
    }]; 


    return location; // note: ALWAYS RETURNs nil 
} 

답변

1

: 같은

내 일반적인 방법은 보인다. 요청이 진행되는 동안 요청자를 차단하면 안됩니다. 대신 블록을 일반적인 방법으로 전달해야합니다.이 블록은 RestKit으로 전달한 블록에서 실행됩니다. 이를 통해 요청의 비동기 성격을 적절하게 존중할 수 있습니다.

차단을 계속하고 싶다면 세마포어를 사용하여보세요. 그러나이 문제를 스스로 해결해야합니다. 그리고 주 스레드에서 요청을 트리거 할 수 없습니다. 이는 일반적인 사용에있어 중요한 장애물이며 앞으로 문제가 발생할 수 있습니다.

+0

감사합니다. 나는 기존의 일반적인 방법에 또 다른 블록 매개 변수를 만든다. 따라서 일반 메소드를 호출하는 모든 코드는 일반적인 메소드에서 RestKit의 콜백 성공 함수에서 실행되도록 블록을 전달해야합니다. –