0

我正在将我的 iPhone 应用程序转换为 iPad,但我遇到了转换问题。我有一个创建一些缩略图的背景线程。

问题似乎是应用程序循环通过数组并输出所有项目,但似乎只有最后一个项目正在加载 UIButton 文本。在所有之前的按钮显示文本之前,有 5-15 秒的延迟。

UIImage *tmp = [self thumbnailImage:[effect objectAtIndex:0] thumbnailType:@"category"];

for (id effect in effectArray) {

    UIImage *tmp = [self thumbnailImage:[effect objectAtIndex:0] thumbnailType:@"category"];

    dispatch_async(dispatch_get_main_queue(), ^{

        UIView *effectView = [[UIView alloc] initWithFrame:CGRectMake(item_x_axis, current_row_height, item_width, item_height)];

        UIImageView *imagepreview = [[UIImageView alloc] init];
        [imagepreview setFrame:CGRectMake(20, 20, 100, 100)];
        [imagepreview setImage:tmp];
        imagepreview.contentMode = UIViewContentModeScaleAspectFit;
        imagepreview.layer.shadowColor = [UIColor blackColor].CGColor;
        imagepreview.layer.shadowOffset = CGSizeMake(0, 1);
        imagepreview.layer.shadowOpacity = 1;
        imagepreview.layer.shadowRadius = 2.0;
        imagepreview.clipsToBounds = NO;
        [effectView addSubview:imagepreview];

        if([[effect objectAtIndex:3]  isEqualToString:@"iap"]){

            UIImageView *buttonPlus = [[UIImageView alloc] init];
            [buttonPlus setFrame:CGRectMake(54, 66, 23, 23)];
            [buttonPlus setImage:[UIImage imageNamed:@"ButtonPlus.png"]];
            [effectView addSubview:buttonPlus];

        }

        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        [button addTarget:self action:NSSelectorFromString([effect objectAtIndex:1]) forControlEvents:UIControlEventTouchDown];
        [button setTitle:[effect objectAtIndex:2] forState:UIControlStateNormal];
        button.frame = CGRectMake(0, 0, item_width, item_height);
        button.titleLabel.font = [UIFont systemFontOfSize:11];
        [button setTitleShadowColor:[UIColor blackColor] forState:UIControlStateNormal];
        [button.titleLabel setShadowOffset:CGSizeMake(1.0f, 1.0f)];
        [button setTitleEdgeInsets:UIEdgeInsetsMake(120, 0, 0.0, 0.0)];
        [effectView addSubview:button];


        [self.viewScrollCategories addSubview:effectView];

        button = nil;

    });

    if(current_items_per_row < 3){
        current_items_per_row++;
        item_x_axis = item_x_axis + item_width;
    }else {
        current_row_height = current_row_height + item_height;
        current_items_per_row = 1;
        item_x_axis = 0;
    }

}

知道如何解决这个问题吗?它似乎在 iPhone 上运行良好。

编辑

这是调用后台线程的代码(缩短)

- (void)imagePickerController:( UIImagePickerController *)picker didFinishPickingMediaWithInfo: (NSDictionary *)info {


//[self generatingThumbnailMessageShow];

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    [self loadAllEffects];
    dispatch_async(dispatch_get_main_queue(), ^{
        [self generatingThumbnailMessageHide];
    });
});

}
4

1 回答 1

2

好吧,您要求延迟dispatch_async(dispatch_get_main_queue().... 该代码的意思是“请在我当前代码完成运行后的某个时间,只要有时间就这样做。” 一旦你这么说,你基本上是在说你不在乎这段代码什么时候运行。您希望很快就会有一段时间,但您已经离开运行时来处理细节。

所以也许正是这个“希望”才是问题所在。设备处理器的体系结构不同,设备的线程模型可能会改变设备响应这些延迟请求堆积的方式。

我完全不清楚您要在此代码中完成什么(抱歉,tl:dr),但在其中使用延迟性能以及您抱怨“5-15 秒延迟”似乎是以某种方式在一起...

编辑:好的,我现在看到您的代码正在后台运行,并且您正在使用dispatch_async单步到主线程以修改界面。因此,问题可能在于您引用的代码,而在于您用于管理后台线程的代码。

另一个编辑:这里只是一个疯狂而疯狂的想法。如果图像处理需要时间,为什么不进行所有图像处理,然后在主线程上更新一次界面?我的意思是,你正在这样做:

for (id effect in effectArray) {
    UIImage *tmp = // ...
    dispatch_async(dispatch_get_main_queue(), ^{
        // ...
        [imagepreview setImage:tmp];

所以你每次通过循环都重复回到主线程。为什么不试试这个:

dispatch_async(dispatch_get_main_queue(), ^{
    for (id effect in effectArray) {
        UIImage *tmp = // ...
        // ...
        [imagepreview setImage:tmp];

现在你只是回到主线程一次。图像处理过程中会有延迟,但界面应该只是更新,badda bing badda boom(技术编程术语)。

于 2013-04-14T18:42:58.553 回答