2

每次用户点击刷新按钮时,我基本上都是从服务器加载图像。然而,这种加载机制冻结了主线程,所以我决定尝试使用 GCD 将图像加载到不同的线程中。我看过教程,似乎我设置正确,但我仍然遇到同样的问题。

我的代码:

-(IBAction)refreshButton:(id)sender{

    dispatch_queue_t myQueue = dispatch_queue_create("My Queue",NULL);

    dispatch_async(myQueue, ^{
        [[API sharedInstance] commandWithParams:[NSMutableDictionary dictionaryWithObjectsAndKeys:
                                                 @"stream",@"command",@"0",@"IdImage",_contentFilter,@"contentFilter",
                                                 nil]
                                   onCompletion:^(NSDictionary *json){
                                       NSMutableArray *tempArray = [json objectForKey:@"result"];
                                       NSMutableArray *tempDataArray = [[NSMutableArray alloc] initWithCapacity:[_imagesTemporaryHolder count]];
                                       NSLog(@"loaded temporary image holder");
                                       for (int i=0;i<[_images count];i++) {
                                           NSLog(@" populating _imagesData");
                                           NSString *imageID = [[tempArray objectAtIndex:i] objectForKey:@"IdImage"];
                                           NSString *imageURL = [NSString stringWithFormat:@"http://swiphtapp.com/Swipht/upload/%@.jpg",imageID];
                                           NSData *tempImageData = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString:imageURL]];
                                           [tempDataArray insertObject:tempImageData atIndex:i];
                                        }


                                   }];

        dispatch_async(dispatch_get_main_queue(), ^{
            // Update the UI

        });
    });

}

难道是我需要去 API 类并在那里改变一些东西吗?顺便说一句,我正在使用AFNNETWORKING

非常感谢你的帮助!

更新 1

看起来 API 的“onCompletion”块是导致问题的原因......我在其中进行了 NSLog(isMainThread) 检查,它返回 YES 意味着它正在主线程中运行,尽管它不应该像我一样将其封装在 GCD 中。关于如何解决这个问题的想法?

感谢真棒的人回答

@eric

API 调用的完成块是在主线程上执行的,因为您通常会在主线程上根据收到的数据更新视图。尝试将您的 GCD 内容放在完成块内,而不是将整个内容封装在其中。在主线程上花费了很长时间,因为您从原始 API 调用返回的 url 中获取 NSData,这可能需要很长时间(相对而言)

基本上,GCD 需要在 API 调用的完成块中。

再次感谢!

4

1 回答 1

0

我相信这是我们在最初帖子下的评论中得出的答案:

-(IBAction)refreshButton:(id)sender
{
    [[API sharedInstance] commandWithParams:[NSMutableDictionary dictionaryWithObjectsAndKeys:
                                             @"stream",@"command",@"0",@"IdImage",_contentFilter,@"contentFilter",
                                             nil]
                               onCompletion:^(NSDictionary *json){

                                   dispatch_queue_t myQueue = dispatch_queue_create("My Queue",NULL);

                                   dispatch_async(myQueue, ^{
                                       NSMutableArray *tempArray = [json objectForKey:@"result"];
                                       NSMutableArray *tempDataArray = [[NSMutableArray alloc] initWithCapacity:[_imagesTemporaryHolder count]];
                                       NSLog(@"loaded temporary image holder");
                                       for (int i=0;i<[_images count];i++) {
                                           NSLog(@" populating _imagesData");
                                           NSString *imageID = [[tempArray objectAtIndex:i] objectForKey:@"IdImage"];
                                           NSString *imageURL = [NSString stringWithFormat:@"http://swiphtapp.com/Swipht/upload/%@.jpg",imageID];
                                           NSData *tempImageData = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString:imageURL]];
                                           [tempDataArray insertObject:tempImageData atIndex:i];
                                        }
                                       dispatch_async(dispatch_get_main_queue(), ^{
                                           // Update the UI

                                       });
                                   });
                               }];
}
于 2013-07-22T22:45:59.530 回答