2012-05-21 2 views
1

Я пытаюсь загрузить изображения в фоновом режиме с помощью gcd. Моя первая попытка не работает:Загрузить UIImage из файла с помощью центральной центральной отправки

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW,0), ^{ 
    dispatch_async(dispatch_get_main_queue(), ^{ 
    // create UI Image, add to subview 
    }); 
}); 

закомментировать код фона очереди, оставляя только основной очереди отправки блок не работает:

dispatch_async(dispatch_get_main_queue(), ^{ 
    // create UI Image, add to subview 
}); 

Есть некоторые хитрости, чтобы делать вещи внутри щ блок gcd?

В ответ на комментарий mattjgalloway я просто пытаюсь загрузить большое изображение в фоновом потоке. Вот полный код, который я пытался изначально:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW,0), ^{ 

    UIImage* img = [[UIImage alloc] initWithContentsOfFile: path]; 

    dispatch_async(dispatch_get_main_queue(), ^{ 

     imageView = [[[UIImageView alloc] initWithImage: img] autorelease]; 
     imageView.contentMode = UIViewContentModeScaleAspectFill; 
     CGRect photoFrame = self.frame; 
     imageView.frame = photoFrame; 
     [self addSubview:imageView]; 

    }); 

}); 

Я упрощена так, что я бегала все внутри главной очереди, но даже тогда он не работает. Я полагаю, что если я не смогу заставить все работать в главной очереди, это не повлияет на работу в фоновом режиме.


================ ОБНОВЛЕНИЕ ==============

Я попытался выше технику (GCD и все) в совершенно новом проекте, и он действительно работает так, как ожидалось. Просто не в моем текущем проекте. Поэтому мне придется сделать медленный, болезненный процесс устранения, чтобы выяснить, что происходит. Я использую эту фоновую загрузку для отображения изображений в uiscrollview. Оказывается, биты изображений иногда появляются, но не всегда. Я доберусь до конца этого ...

=============== ОБНОВЛЕНИЕ ===============

Похоже, что проблема связана с UIScrollView, все это внутри. Я думаю, что материал не становится нарисованным/освеженным, когда он должен

+0

Что вы пытаетесь достичь? Вы действительно не хотите просто отправлять в фоновый режим, а затем в основную очередь - чего вы ожидали от этого? Покажите нам еще один код того, что вы пробовали. – mattjgalloway

+0

@mattjgalloway Просто пытается загрузить изображение в фоновом режиме. Более подробный код, вставленный выше. – morgancodes

+0

Что не работает? – mattjgalloway

ответ

1

Я запустил ваш код. Он работает с одним исключением. Также вы имели в виду self.view, а не я?

Случай 1:

путь объявлен в собственности.
ImageView объявляется на Ивар

- (IBAction)buttonImagePressed:(id)sender 
{ 
    self.path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"picture1.jpg"]; 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW,0), ^{ 
     UIImage* img = [[UIImage alloc] initWithContentsOfFile: self.path]; 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      imageView = [[[UIImageView alloc] initWithImage: img] autorelease]; 
      imageView.contentMode = UIViewContentModeScaleAspectFill; 
      CGRect photoFrame = self.view.frame; 
      imageView.frame = photoFrame; 
      [self.view addSubview:imageView]; 
     }); 
    }); 
} 

Случай 2:

пути и ImageView оба Иварс. - не используется свойство.

- (IBAction)buttonImagePressed:(id)sender 
{ 
// will crash if path is defined here 
// path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"picture1.jpg"]; 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW,0), ^{ 
     //if path is defined here then it will work 
     path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"picture1.jpg"]; 
     UIImage* img = [[UIImage alloc] initWithContentsOfFile:path]; 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      imageView = [[[UIImageView alloc] initWithImage: img] autorelease]; 
      imageView.contentMode = UIViewContentModeScaleAspectFill; 
      CGRect photoFrame = self.view.frame; 
      imageView.frame = photoFrame; 
      [self.view addSubview:imageView]; 
     }); 
    }); 
} 

На случай 2, где он упал, сообщение в консоли сказали об ошибке на сайте apple.com ...

+0

Хм. Благодарю. Я имел в виду взгляд, а не self.view. Мой код запущен внутри подкласса UIView, который пытается добавить subview к себе. Итак, случай 2 (как представлено, с комментариями прокомментировал) работал отлично для вас? – morgancodes

+0

Да. И я пробовал мой код выше в подклассе UIView и испытывал подобное поведение. Есть ошибка. – user523234

1

Try позвонить setNeedDisplay сразу после [self addSubview:imageView], кстати большинство UIKit не является потокобезопасным, я не знаю о методах UIImage конкретно (возможно, это нормально на iOS4 и выше), но я бы этого не сделал. Если вы хотите загружать изображения из фона, лучше используйте ImageIO, который является потокобезопасным, или функции Core Graphics.
Альтернативой может быть загрузка объекта NSData с вашими данными изображения в фоновом потоке и последующим вызовом [UIImage alloc]inithWithData: data] в основной теме.

+0

Пробовал наборNeedDisplay. – morgancodes

0

Отображение моего изображения в качестве фонового изображения, а не UIImageView, добавленного в качестве подвью.Нет подсказки почему

@interface PhotoView(){ 
    UIImageView* imageView; 
} 

@end 


@implementation PhotoView 

-(id)initWithFrame:(CGRect)frame andPathToPhoto:(NSString*)path andSequenceView:(SequencerView*) sequencerView{ 
    if(self = [super initWithFrame:frame]){ 


    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW,0), ^{ 
     UIImage* img = [[UIImage alloc] initWithContentsOfFile: path]; 
     dispatch_async(dispatch_get_main_queue(), ^{ 
     self.backgroundColor = [UIColor colorWithPatternImage:img]; 
     }); 
     [img release]; 
    }); 

    } 
    return self; 
} 

@end 
Смежные вопросы