这是因为设置是JSONObjectsCollection
异步发生的。因此,您的方法JSONObjectsCollection
在设置之前返回。
因此,它可能看起来像:
- (void)retrieveAtEndpoint:(NSString *)endpointURL withRootNode:(NSString *)rootNode
{
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat: endpointURL, fuegoWSURL]];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
NSDictionary *dict = (NSDictionary *) JSON;
[self setJSONObjectsCollection: [dict objectForKey:rootNode]];
// do here whatever you want to do now that you have your array, e.g.
//
// [self.tableView reloadData];
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
NSLog(@"Communication Error: %@", error);
}];
[operation start];
}
请注意,retrieveAtEndpoint
现在有一个void
返回类型,但在完成块中,我将调用您想要在更新 JSON 对象集合后执行的任何代码。
如果这是模型对象中的一个方法,但您想提供一个接口,视图控制器可以通过该接口提供一个在成功检索 JSON 时应执行的代码块,请使用完成块:
- (void)retrieveAtEndpoint:(NSString *)endpointURL withRootNode:(NSString *)rootNode completion:(void (^)(NSError *error))completion
{
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat: endpointURL, fuegoWSURL]];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
NSDictionary *dict = (NSDictionary *) JSON;
[self setJSONObjectsCollection: [dict objectForKey:rootNode]];
if (completion)
{
completion(nil);
}
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
if (completion)
{
completion(error);
}
}];
[operation start];
}
或者,如果您想简化块参数的使用,您可以在模型对象的 .h 文件的开头(@interface
块之前)定义完成块的类型:
typedef void (^RetrievalCompleteBlock)(NSError *);
然后将方法简化一点:
- (void)retrieveAtEndpoint:(NSString *)endpointURL withRootNode:(NSString *)rootNode completion:(RetrievalCompleteBlock)completion
{
// the code here is like it is above
}
无论如何,无论您是否使用typedef
,视图控制器都可以执行以下操作:
ModelObject *object = ...
NSString *rootNode = ...
[object retrieveAtEndpoint:url withRootNode:rootNode completion:^(NSError *error) {
if (error)
{
// handle the error any way you want, such as
NSLog(@"%s: retrieveAtEndPoint error: %@", __FUNCTION__, error);
}
else
{
// do whatever you want upon successful retrieval of the JSON here
}
}];
此处的详细信息将根据您的视图控制器访问模型对象的方式、知道根节点应该是等等而有所不同。我经常会在我的完成块中包含另一个参数,即正在检索的数据,但是假设您更新了您的模型对象并可以通过这种方式访问它,也许这不是必需的。我只是没有足够的关于你的实现的细节来知道这里有什么,所以我让我的实现尽可能地简约。
但希望这能说明这个想法。给你的retrieveAtEndpoint
方法一个完成块参数,它让视图控制器指定它在与服务器通信完成(或失败)时想要做什么。