我是新手在iOS中使用块,我认为这可能是我问题的症结所在。
我只想构建一个简单的静态DataManager类,其唯一的工作是从Restful服务中获取数据。
我会从各种各样的UIViewControllers(或collectionview / table controllers)
中调用它在我的课堂上,我有一个看起来像这样的功能
+ (NSArray *) SearchByKeyword: (NSString*) keyword {
__block NSArray* searchResults = [[NSArray alloc] init];
NSString *baseURL = @"http://someURL.com/api/search";
NSString *requestURL = [baseURL stringByAppendingString:keyword];
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:baseURL]];
NSMutableURLRequest *request = [httpClient requestWithMethod:@"GET"
path:requestURL
parameters:nil];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
searchResults = [JSON valueForKeyPath:@""];
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
NSLog(@"Request Failed with Error: %@, %@", error, error.userInfo);
}];
[operation start];
return searchResults;
}
然而,这会不断返回零数据。有人可以提出正确的方法吗?
答案 0 :(得分:7)
您正在尝试将异步任务的结果(JSON操作)用作同步方法调用的返回值,这就是您没有数据的原因。
您可以为视图控制器提供一个API,该API采用完成块和故障块,类似于AF网络。然后,视图控制器可以在将结果传递到块中时执行结果所需的操作。
根据您的问题修改代码:
typedef void (^SearchCompletionBlock)(NSArray *results);
typedef void (^SearchFailureBlock)(NSError *error);
+ (void)searchByKeyword:(NSString*)keyword completionBlock:(SearchCompletionBlock)completionBlock failureBlock:(SearchFailureBlock)failureBlock;
{
NSString *baseURL = @"http://someURL.com/api/search";
NSString *requestURL = [baseURL stringByAppendingString:keyword];
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:baseURL]];
NSMutableURLRequest *request = [httpClient requestWithMethod:@"GET"
path:requestURL
parameters:nil];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request
success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
if (completionBlock) {
completionBlockc([JSON valueForKeyPath:@""]);
}
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
NSLog(@"Request Failed with Error: %@, %@", error, error.userInfo);
if (failureBlock) {
failureBlock(error);
}
}];
[operation start];
}
然后,客户端可以传递存储结果的完成块并重新加载其视图。类似的东西:
^ (NSArray *results) {
self.results = results;
[self.tableView reloadData];
}
答案 1 :(得分:1)
您的JSON请求操作是异步的,这意味着它将启动请求([operations start]
,然后立即返回结果,这将是空的。当完成块运行时,它会分配您的数据,但什么也没做除非等待请求完成,否则您的搜索方法无法返回对象。
你有几个选择:
将完成块传递给搜索方法,该搜索方法对结果执行某些操作。一旦所有特定于服务的东西(处理JSON等)完成,就在请求的完成块中调用完成块。 (阻止开始!)
让请求的完成块分配数据管理器的属性,然后调用委托方法或通知,让其他人知道结果可用。
我更喜欢选项1.