Objective-C - 阻止循环继续直到调用委托方法
Objective-C - block loop from continuing until delegate method is called
在每个循环中,我使用用于执行 JSON 调用的 ID 初始化连接器 class。问题是,此循环在连接器 class 的 connectionDidFinishLoading 委托方法完成之前继续迭代,根据需要解析 JSON,然后使用委托方法及其检索到的信息。
for(NSDictionary *item in views){
NSInteger myID = [[item valueForKey:@"id"] integerValue];
//filter contains these two dictionaries
NSDictionary *ownerDictionary = [filterDictionary valueForKey:@"owner"];
NSString *ownerDisplayName = [ownerDictionary valueForKey:@"displayName"];
self.projectName = projectName;
self.ownerName = ownerDisplayName;
//value inside dictionary for owner
NSString *ownerDisplayName = [ownerDictionary valueForKey:@"displayName"];
//I initialize the connector class here
self.sprintConnector = [[SprintConnector alloc] initWithId:myID];
[self.sprintConnector setDelegate:self];
//**I do not want to continue this loop until the delegate method that i implement is called**/
}
//implementation of delegate method
-(void)didFinishLoadingStuff:(MyObject *)obj{
Project *newProject = [[Project alloc] init];
newProject.projectName = self.projectName;
newProject.projectOwner = self.ownerName;
newProject.sprint = sprint;
//Ok now i have the information that i need, lets continue our loop above
}
//连接器class设置请求的方法在这里:
-(void)retrieveSprintInfoWithId{
NSURLConnection *conn;
NSString *urlString = @"myJSONURL";
NSURL *url = [NSURL URLWithString:[urlString stringByAppendingString:self.ID]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
// conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
conn = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
NSLog(@"data coming from request: %@", data );
[self.data appendData:data];
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{
NSLog(@"we finished loading");
NSError *error = nil;
self.projectsDict = [[NSDictionary alloc] initWithDictionary:[NSJSONSerialization JSONObjectWithData:self.data options:NSJSONReadingMutableContainers error:&error]];
NSLog(@"Our sprint array with id: %@ %@", self.ID, self.projectsDict);
//this is where we parse the JSON then use the delegate method that the above class will implement
[self parseJSON];
}
-(void)parseJSON{
[self.delegate didFinishLoadingStuff:SomeObject];
}
我希望能够强制调用 connectionDidFinishLoading 方法 ->parseJSON->delegate 方法,并在循环继续之前完成上述方法的实现。
我有哪些选择?最佳实践? ETC?
你想做的是同步发出请求,我会告诉你怎么做,但你不应该那样做,所以在我告诉你如何发出同步请求之后,我会告诉你如何做应该处理这个
1- 要同步发出请求,您可以使用 NSURLConnection 的 sendSynchronousRequest
方法,这将阻塞直到接收到数据和 return 数据,这里是 docs。你不应该这样做,因为你可能会阻塞主线程,这会导致糟糕的用户体验(还有其他原因导致这是不好的做法)
2- 你应该像在示例代码中那样发出异步请求,在你的回调中你应该获取适当的对象(你应该通过项目 ID 知道),然后做你需要的任何事情对该对象执行操作...如果您需要加载所有内容以便执行某些操作,那么您应该跟踪它(发送的请求与收到的响应)
希望对您有所帮助
丹尼尔
在每个循环中,我使用用于执行 JSON 调用的 ID 初始化连接器 class。问题是,此循环在连接器 class 的 connectionDidFinishLoading 委托方法完成之前继续迭代,根据需要解析 JSON,然后使用委托方法及其检索到的信息。
for(NSDictionary *item in views){
NSInteger myID = [[item valueForKey:@"id"] integerValue];
//filter contains these two dictionaries
NSDictionary *ownerDictionary = [filterDictionary valueForKey:@"owner"];
NSString *ownerDisplayName = [ownerDictionary valueForKey:@"displayName"];
self.projectName = projectName;
self.ownerName = ownerDisplayName;
//value inside dictionary for owner
NSString *ownerDisplayName = [ownerDictionary valueForKey:@"displayName"];
//I initialize the connector class here
self.sprintConnector = [[SprintConnector alloc] initWithId:myID];
[self.sprintConnector setDelegate:self];
//**I do not want to continue this loop until the delegate method that i implement is called**/
}
//implementation of delegate method
-(void)didFinishLoadingStuff:(MyObject *)obj{
Project *newProject = [[Project alloc] init];
newProject.projectName = self.projectName;
newProject.projectOwner = self.ownerName;
newProject.sprint = sprint;
//Ok now i have the information that i need, lets continue our loop above
}
//连接器class设置请求的方法在这里:
-(void)retrieveSprintInfoWithId{
NSURLConnection *conn;
NSString *urlString = @"myJSONURL";
NSURL *url = [NSURL URLWithString:[urlString stringByAppendingString:self.ID]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
// conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
conn = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
NSLog(@"data coming from request: %@", data );
[self.data appendData:data];
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{
NSLog(@"we finished loading");
NSError *error = nil;
self.projectsDict = [[NSDictionary alloc] initWithDictionary:[NSJSONSerialization JSONObjectWithData:self.data options:NSJSONReadingMutableContainers error:&error]];
NSLog(@"Our sprint array with id: %@ %@", self.ID, self.projectsDict);
//this is where we parse the JSON then use the delegate method that the above class will implement
[self parseJSON];
}
-(void)parseJSON{
[self.delegate didFinishLoadingStuff:SomeObject];
}
我希望能够强制调用 connectionDidFinishLoading 方法 ->parseJSON->delegate 方法,并在循环继续之前完成上述方法的实现。
我有哪些选择?最佳实践? ETC?
你想做的是同步发出请求,我会告诉你怎么做,但你不应该那样做,所以在我告诉你如何发出同步请求之后,我会告诉你如何做应该处理这个
1- 要同步发出请求,您可以使用 NSURLConnection 的 sendSynchronousRequest
方法,这将阻塞直到接收到数据和 return 数据,这里是 docs。你不应该这样做,因为你可能会阻塞主线程,这会导致糟糕的用户体验(还有其他原因导致这是不好的做法)
2- 你应该像在示例代码中那样发出异步请求,在你的回调中你应该获取适当的对象(你应该通过项目 ID 知道),然后做你需要的任何事情对该对象执行操作...如果您需要加载所有内容以便执行某些操作,那么您应该跟踪它(发送的请求与收到的响应)
希望对您有所帮助
丹尼尔