У меня есть UIView с подвью UIImageView. Мне нужно загрузить изображение в UIImageView без блокировки пользовательского интерфейса. Блокирующий вызов выглядит следующим образом: UIImage imageNamed:
. Вот что я решил решить эту проблему:
-(void)updateImageViewContent {
dispatch_async(
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
UIImage * img = [UIImage imageNamed:@"background.jpg"];
dispatch_sync(dispatch_get_main_queue(), ^{
[[self imageView] setImage:img];
});
});
}
Изображение маленькое (150x100).
Однако пользовательский интерфейс по-прежнему блокируется при загрузке изображения. Что мне не хватает?
Вот небольшой пример кода, который проявляет это поведение:
Создайте новый класс на основе UIImageView, установите его взаимодействие с пользователем YES, добавьте два экземпляра в UIView и реализуйте его метод touchhesBegan следующим образом:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if (self.tag == 1) {
self.backgroundColor= [UIColor redColor];
}
else {
dispatch_async(dispatch_get_main_queue(), ^{
[self setImage:[UIImage imageNamed:@"woodenTile.jpg"]];
});
[UIView animateWithDuration:0.25 animations:
^(){[self setFrame:CGRectInset(self.frame, 50, 50)];}];
}
}
Назначьте тег 1 одному из этих изображений.
Что происходит, когда вы одновременно используете два вида просмотра, начиная с представления, загружающего изображение? Заблокирован ли пользовательский интерфейс, потому что он ждет возврата [self setImage:[UIImage imageNamed:@"woodenTile.jpg"]];
? Если да, то как я могу сделать это асинхронно?
Вот проект на github с кодом ipmcc
Используйте длинное нажатие, затем перетащите, чтобы нарисовать прямоугольник вокруг черных квадратов. Насколько я понимаю его ответ, теоретически белый прямоугольник выбора не должен блокироваться при первом загрузке изображения, но на самом деле это.
В проект включены два изображения (один маленький: woodenTile.jpg и еще один: bois.jpg). Результат одинаковый с обоими.
Формат изображения
Я действительно не понимаю, как это связано с проблемой, которую я все еще имею, когда пользовательский интерфейс блокируется во время загрузки изображения в первый раз, но изображения PNG декодируются без блокировки пользовательского интерфейса, в то время как изображения JPG блокируют пользовательский интерфейс.
Хронология событий
Здесь начинается блокировка пользовательского интерфейса.
.. и заканчивается здесь.
Решение AFNetworking
NSURL * url = [ [NSBundle mainBundle]URLForResource:@"bois" withExtension:@"jpg"];
NSURLRequest * request = [NSURLRequest requestWithURL:url];
[self.imageView setImageWithURLRequest:request
placeholderImage:[UIImage imageNamed:@"placeholder.png"]
success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
NSLog(@"success: %@", NSStringFromCGSize([image size]));
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
NSLog(@"failure: %@", response);
}];
// this code works. Used to test that url is valid. But it blocking the UI as expected.
if (false)
if (url) {
[self.imageView setImage: [UIImage imageWithData:[NSData dataWithContentsOfURL:url]]]; }
В большинстве случаев он регистрируется: success: {512, 512}
Он также может использовать журналы: success: {0, 0}
И иногда: failure: <NSURLResponse: 0x146c0000> { URL: file:///var/mobile/Appl...
Но изображение никогда не изменяется.