2015-03-19 49 views
0

我想从服务器使用一些示例代码检索一些数据,如下所示。然而,它给了我不可预知的结果。我不确定这是因为该块在回路中被取消分配或在内存中被覆盖。 基本上数据不符合我期望的指数。目标C块和For循环

-(void)retrieveSomeStuff { 

    for (int i = 0 ; i < items.count; i++) 
    { 
     [self retrieveDataForIndex:i 
       completionHandler:^(NSDictionary *data, NSError *error) { 


       }]; 

    } 
} 

-(void) retrieveDataForIndex:i completionHandler:(void(^)(NSDictionary *,NSError*) completionHandler { 

    [NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 
     completionHandler(data,connectionError); 
    } 

} 

处理这种情况的最好方法是什么?

+0

仍然使用MMM代替ARC? – 2015-03-19 06:31:34

+0

如果您想逐一处理,您应该只创建一个操作队列。像静态NSOperationQueue *队列;如果(!队列)队列= [[NSOperationQueue分配]初始化]; queue.maxConcurrentCount = 1;然后sendAsynchronousRequest – Suen 2015-03-19 06:35:17

+0

您的代码不会执行任何内容。你想展示什么不起作用? – newacct 2015-03-19 19:16:42

回答

-1

为避免重新分配,您必须复制方法“retrieveDataForIndex”中的块。请参阅下面的修改。

typedef void(^CompletionHandler)(NSData * data, NSError * error); 

-(void) retrieveDataForIndex:(NSInteger)i completionHandler:(CompletionHandler)Completion 
{ 
    CompletionHandler _completionHandler = [Completion copy]; 
    NSURLRequest * request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.google.co.in"]]; 

[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) 
{ 
    _completionHandler(data, connectionError); 
    [_completionHandler release]; 
}]; 
} 

-(void)retrieveSomeStuff 
{ 
    for (int i = 0 ; i < 10; i++) 
    { 
     [self retrieveDataForIndex:i completionHandler:^(NSData *data, NSError *error) 
     { 
     NSLog(@"\nData Received"); 
     }]; 
    } 
} 
+0

是否在一次迭代后“CompletionHandler _completionHandler”变量被覆盖? – rustylepord 2015-03-19 06:59:23

+1

否,因为我们每次使用“复制”方法创建块的新副本,并将此新块地址用于“sendAsynchronousRequest”的完成块中。这就是“sendAsynchronousRequest”在向其传递块时的工作方式。 – 2015-03-19 07:09:41

+0

这个副本是完全没有必要的。如果'Completion'在传递给操作队列中的块直接使用,那么,如果该块曾经被复制(其必须,以便它能够被存储和异步地执行),它将保留对象的指针类型的所有变量和复制它捕获的块指针类型的所有变量。 – newacct 2015-03-19 19:14:15