2013-07-14 37 views
12

Tôi đang sử dụng AFNetworking để lấy dữ liệu từ một máy chủ:Return giá trị cho chức năng bên trong một khối

-(NSArray)some function { 
    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request 
     success: ^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) { 
      NSArray *jsonArray =[JSON valueForKey:@"posts"]; 
     } 
     failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {} 
} 

Vì vậy, những gì tôi đang cố gắng để làm ở đây là để trả lại jsonArray đến chức năng. Rõ ràng trở lại không hoạt động.

+9

Bạn không thể thực hiện việc này. Vì bạn đang đối phó với một cuộc gọi không đồng bộ, phương thức 'some function' của bạn sẽ trả về lâu trước khi có một giá trị trả về. – rmaddy

+2

Tôi khuyên bạn nên lùi lại một bước và suy nghĩ về mã của bạn. Bạn sẽ sớm nhận ra rằng những gì bạn muốn không có ý nghĩa. –

+1

bạn có thể vượt qua các khối để hoạt động sẽ thực hiện thành công hoặc lỗi. – stosha

Trả lời

19

Bạn không thể sử dụng khối hoàn thành để tạo giá trị trả lại cho phương thức của mình. AFJSONRequestOperation hoạt động không đồng bộ. someFunction sẽ trở lại trong khi thao tác vẫn hoạt động. Các khối thành công và thất bại là cách bạn nhận được các giá trị kết quả mà chúng cần đến.

Một tùy chọn ở đây là chuyển người gọi làm đối số cho phương thức trình bao bọc của bạn để Khối hoàn thành có thể giao mảng đó.

- (void)goFetch:(id)caller 
{ 
    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request 
    success: ^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) { 

     [caller takeThisArrayAndShoveIt:[JSON valueForKey:@"posts"]]; 
    } 
    failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {} 
} 

Bạn cũng có thể làm cho người gọi của mình tạo và vượt qua Chặn để chạy thành công. Sau đó, goFetch: không còn cần biết thuộc tính nào tồn tại trên người gọi.

- (void)goFetch:(void(^)(NSArray *))completion 
{ 
    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request 
    success: ^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) { 
     if(completion) completion([JSON valueForKey:@"posts"]); 
    } 
    failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {} 
} 
+4

takeThisArrayAndShoveIt - lol trên tên phương thức –

3

Như những người khác đã nói, bạn không thể làm điều đó khi xử lý cuộc gọi không đồng bộ. Thay vì trả lại mảng được mong đợi, bạn có thể chuyển khối hoàn thành dưới dạng tham số

typedef void (^Completion)(NSArray* array, NSError *error); 

-(void)someFunctionWithBlock:(Completion)block { 
    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request 
     success: ^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) { 
      NSArray *jsonArray =[JSON valueForKey:@"posts"]; 
      if (block) block(jsonArray, nil); 
     } 
     failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) { 
      if (block) block(nil, error); 
     } 
} 

Sau đó, bạn gọi hàm đó là một số chức năng. Mã này cũng sẽ xử lý lỗi thích hợp cho bạn.

[yourClassInstance someFunctionWithBlock:^(NSArray* array, NSError *error) { 
    if (error) { 
     NSLog(%@"Oops error: %@",error.localizedDescription); 
    } else { 
     //do what you want with the returned array here. 
    } 
}]; 
0

tôi phải đối mặt với loại sự cố này và giải quyết bằng phương pháp này bên dưới. Tôi đã thấy các câu trả lời ở trên bằng cách sử dụng các khối. Nhưng giải pháp này phù hợp hơn vào thời điểm đó. Logic của phương pháp rất đơn giản. Bạn cần gửi đối tượng và phương thức của nó như một tham số và sau khi yêu cầu hoàn thành, phương thức đó sẽ được gọi. Hy vọng điều đó sẽ hữu ích.

+(void)request:(NSString *)link parameters:(NSDictionary *)params forInstance:(id)instance returns:(SEL)returnValue 
{ 
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; 
    [manager GET:link 
     parameters:params 
     success:^(AFHTTPRequestOperation *operation, id responseObject) 
    { 
     [instance performSelector:returnValue withObject: responseObject]; 
    } 
     failure:^(AFHTTPRequestOperation *operation, NSError *error) 
    { 
     [instance performSelector:returnValue withObject:nil]; 
     //NSLog(@"Error: %@", error); 
    }]; 
} 
Các vấn đề liên quan