多个Web服务使UI无响应

时间:2015-09-17 10:49:18

标签: ios

问题是我在我的主页上调用了多个webservices,webservice正在从服务器返回图像和文本。在这个过程中,UI变得完全没有响应,比如说1-2分钟,这看起来非常糟糕,因为我无法做任何事情。我听说过调度并尝试实施它,但我没有得到任何结果。可能我做错了。

我现在想要的是我希望在后台运行此过程以便用户可以在从服务器获取操作期间与UI进行交互。我正在实现我的代码,告诉我在哪里使用dispatch。

-(void)WebserviceHomeSlider{
if([AppDelegate appDelegate].isCheckConnection){

    //Internet connection not available. Please try again.
    UIAlertView *alertView=[[UIAlertView alloc] initWithTitle:@"Internate error" message:@"Internet connection not available. Please try again." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
    [alertView show];
    return;
}else {

    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    manager.responseSerializer.acceptableContentTypes = [manager.responseSerializer.acceptableContentTypes setByAddingObject:@"text/html"];
    [manager GET:ServiceUrl@"fpMainBanner" parameters:nil success:^(AFHTTPRequestOperation *operation,id responseObject)
     {
         //NSLog(@"JSON: %@", responseObject);

         arrSlider = [responseObject objectWithJSONSafeObjects];
         [_slideshow setTransitionType:KASlideShowTransitionSlide];
         _slideshow.gestureRecognizers = nil;
         [_slideshow addGesture:KASlideShowGestureSwipe];
         //         [_slideshow addImagesFromResources:[self getImages]]; // Add
         //         [_slideshow addTextFromResources:[self getText]];
         // [slideShow subtextWithImages:[self getsubText]];


         [_slideshow addImagesFromResources:[self getImages] stringArray:[self getText] stringsubArray:[self getsubText]];

     }
         failure:^(AFHTTPRequestOperation *operation, NSError *error) {
             NSLog(@"Error: %@", error);
         }];



}

}

如果可能,请告诉我在哪里使用调度或编辑我的代码。我已经完成了一些例子,但我的概念仍然不明确。哪种调度方法最佳(DEFAULT或BACKGROUND)。我将非常感谢你。

这是您要查找的代码。告诉我使用dispatch

编辑它的位置
-(NSArray *)getText{
NSMutableArray *textArr = [[NSMutableArray alloc] init];



for(int i=0; i<[arrSlider count];i++)
{


    texxt=[[arrSlider objectAtIndex:i ]valueForKey:@"title" ];
    [textArr addObject:[texxt uppercaseString]];


}


return textArr;

}

- (NSArray *)getsubText {     NSMutableArray * subtext = [[NSMutableArray alloc] init];

for(int i=0; i<[arrSlider count];i++)
{


    subbtext=[[arrSlider objectAtIndex:i ]valueForKey:@"tagline_value" ];
    if(i==8)
    {
        subbtext=@"MAKE YOURSELF STAND OUT GET YOUR FREE CARDS!";


    }
    NSLog(@"subtext is,,.,.,,.,%@.%@",@"k",subbtext);


    [subtext addObject:[subbtext uppercaseString]];



}


return subtext;

}

- (NSArray *)getImages {     NSMutableArray * mArr = [[NSMutableArray alloc] init];

for(int i=0; i<[arrSlider count];i++)
{
    pathh=[[arrSlider objectAtIndex:i ]valueForKey:@"filepath" ];

    NSString *newString = [pathh stringByReplacingOccurrencesOfString:@" " withString:@"%20"];



    NSURL *imageURL = [NSURL URLWithString:newString];


    NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
    UIImage *originalImage = [UIImage imageWithData:imageData];

    CGSize destinationSize = CGSizeMake(320, 158);
    UIGraphicsBeginImageContext(destinationSize);
    [originalImage drawInRect:CGRectMake(0,0,destinationSize.width,destinationSize.height)];
    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    //        [whotshotimgview setImage:image];
    [mArr addObject: img];

}


return mArr;

}

6 个答案:

答案 0 :(得分:0)

 [_slideshow addImagesFromResources:[self getImages] stringArray:[self getText] stringsubArray:[self getsubText]];

这里的问题是你没有展示addImagesFromResources方法的实现。您可能必须在此方法中实现GCD,因为我猜您正在获取图像并在UI上设置此主线程被阻止。

答案 1 :(得分:0)

您正尝试从主网之外的线程访问UIView,导致用户界面无响应。

请使用此:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    [_slideshow setTransitionType:KASlideShowTransitionSlide];
         _slideshow.gestureRecognizers = nil;
         [_slideshow addGesture:KASlideShowGestureSwipe];
         //         [_slideshow addImagesFromResources:[self getImages]]; // Add
         //         [_slideshow addTextFromResources:[self getText]];
         // [slideShow subtextWithImages:[self getsubText]];


         [_slideshow addImagesFromResources:[self getImages] stringArray:[self getText] stringsubArray:[self getsubText]];
});

答案 2 :(得分:0)

我认为您的用户界面因下载图片而挂起。
因此,您应该使用SDWebImage库来帮助您缓存图像并防止UI挂起。
使用SDWebImage,您可以在未加载图像的时候显示加载程序,它将缓存图像。
因此,从下次没有下载图像,UI也不会挂起。
完整参考SDWebImage的链接是:
https://github.com/rs/SDWebImage

答案 3 :(得分:0)

此块阻止主UI执行任务,因此请按以下步骤更新此块

for(int i=0; i<[arrSlider count];i++)
    {
        pathh=[[arrSlider objectAtIndex:i ]valueForKey:@"filepath" ];

        NSString *newString = [pathh stringByReplacingOccurrencesOfString:@" " withString:@"%20"];


        dispatch_queue_t myQueue = dispatch_queue_create("My Queue",NULL);
            dispatch_async(myQueue, ^{
                NSURL *imageURL = [NSURL URLWithString:newString];


                NSData *imageData = [NSData dataWithContentsOfURL:imageURL];

                UIImage *originalImage = [UIImage imageWithData:imageData];

                CGSize destinationSize = CGSizeMake(320, 158);
                UIGraphicsBeginImageContext(destinationSize);
                [originalImage drawInRect:CGRectMake(0,0,destinationSize.width,destinationSize.height)];
                UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
                UIGraphicsEndImageContext();
                //        [whotshotimgview setImage:image];
                [mArr addObject: img];

                dispatch_async(dispatch_get_main_queue(), ^{
                    // If you want to refresh your UI simultaniously, you can write statement for that i.e
                    // yourImageView.image = img;
                    // Otherwise remove this queue

                });
            });
    }

答案 4 :(得分:0)

主线程永远不应该用于长时间处理。它用于UI。

AFNetworking提供下载文件的异步功能。您还应该小心使用过多的模拟下载来破坏网络层。我认为4或5是我最后一次测试时的最大值。

因此执行流程应如下所示。

控制器设置幻灯片显示,将图像下载发送到后台线程(由AFNetworking自动处理),将完成块传递给它。在此完成块中,您需要使用GCD将调度重新分配给主线程,dispatch_async调度到dispatch_get_get_main_queue

保持主线程的运行循环可供用户交互。

答案 5 :(得分:0)

这是因为图像正在另一个线程中加载,并且您在获取数据后立即填充滑块。

最好实现KASlidershow的这种协议方法,以更有效的方式使用幻灯片。

  • (UIImage *)slideShow:(KASlideShow *)slideShow imageForPosition:(KASlideShowPosition)的位置 { pathh = [[arrSlider objectAtIndex:i] valueForKey:@“filepath”];

    NSString *newString = [pathh stringByReplacingOccurrencesOfString:@" " withString:@"%20"];
    
    
    dispatch_queue_t myQueue = dispatch_queue_create("My Queue",NULL);
        dispatch_async(myQueue, ^{
            NSURL *imageURL = [NSURL URLWithString:newString];
    
    
            NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
    
            UIImage *originalImage = [UIImage imageWithData:imageData];
    
            CGSize destinationSize = CGSizeMake(320, 158);
            UIGraphicsBeginImageContext(destinationSize);
            [originalImage drawInRect:CGRectMake(0,0,destinationSize.width,destinationSize.height)];
            UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
            UIGraphicsEndImageContext();
            //        [whotshotimgview setImage:image];
            [mArr addObject: img];
    
            return img;
        });
    

    }

我没有尝试代码,但我希望它可以在变量名称中进行少量更改。祝你好运