Comment asynchrone charger une image dans une UIImageView?

J'ai une UIView avec une UIImageView sous-vue. J'ai besoin de charger une image dans le UIImageView sans blocage de l'INTERFACE utilisateur. L'appel de blocage semble être: UIImage imageNamed:. Voici ce que j'ai pensé a résolu ce problème:

-(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];
        });
    });
}

L'image est de petite taille (150x100).

Cependant l'INTERFACE est toujours bloqué lors du chargement de l'image. Ce qui me manque ?

Voici un petit exemple de code qui présente ce comportement:

Créer une nouvelle classe basée sur UIImageView, définir son interaction avec l'utilisateur pour OUI, ajoutez deux instances dans une UIView, et de mettre en œuvre ses touchesBegan méthode comme ceci:

-(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)];}];
    }
}

Attribuer le point 1 de l'un de ces imageViews.

Ce qui se passe exactement lorsque vous appuyez sur les deux points de vue, presque simultanément, à commencer par la vue qui charge une image? L'INTERFACE utilisateur bloqué parce qu'il est en attente pour [self setImage:[UIImage imageNamed:@"woodenTile.jpg"]]; de retour ? Si oui, comment dois-je faire cela de façon asynchrone ?

Ici est un projet sur github avec ipmcc code

Utiliser un long appuyez sur, puis faites glisser pour dessiner un rectangle autour de la carrés noirs. Ce que je comprends sa réponse, en théorie, le blanc rectangle de sélection ne doit pas être bloqué la première fois que l'image est chargée, mais elle ne l'est réellement.

Deux images sont incluses dans le projet (un petit: woodenTile.jpg et une plus grande: bois.jpg). Le résultat est le même avec les deux.

Format d'Image

Je ne comprends pas vraiment comment cela est lié au problème que je reste avec l'INTERFACE utilisateur bloqué alors que l'image est chargée pour la première fois, mais les images PNG décoder sans blocage de l'INTERFACE utilisateur, tandis que des images JPG ne bloquer l'INTERFACE utilisateur.

Chronologie des événements

Comment asynchrone charger une image dans une UIImageView?
Comment asynchrone charger une image dans une UIImageView?

Le blocage de l'INTERFACE utilisateur commence ici..

Comment asynchrone charger une image dans une UIImageView?

.. et se termine ici.

Comment asynchrone charger une image dans une UIImageView?

AFNetworking solution

    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's blocking the UI as expected.
if (false)       
if (url) {
        [self.imageView setImage: [UIImage imageWithData:[NSData dataWithContentsOfURL:url]]]; }

La plupart du temps, il se connecte: success: {512, 512}

Il a aussi parfois des journaux: success: {0, 0}

Et parfois: failure: <NSURLResponse: 0x146c0000> { URL: file:///var/mobile/Appl...

Mais l'image n'est jamais changé.

  • Il vous manque rien. Changement de l'INTERFACE ont toujours synchrone. C'est le meilleur que vous pouvez faire.
  • Quelle est la taille de l'image? Vous trouverez probablement que l'appel de blocage n'est pas le chargement de l'image, mais plutôt à déchirer le contenu de l'image lors de l'affichage de l'image est affichée sur l'écran. Avez-vous essayé de profilage de l'application pour voir où le col de la bouteille est que vous simplement aveuglément en supposant que le chargement de l'image est le problème?
  • J'ai d'abord été chargement de l'image dans une méthode de classe, une seule fois par toutes les instances de la classe. Le blocage ne se produit que la première fois, ce qui me conduisent à penser qu'il a été causé par UIImage imageNamed.
  • Utiliser des instruments pour trouver le col de la bouteille.
  • Voir ma question et de la réponse de here.
  • C'est intéressant .La accepté de répondre ressemble à ce que ipmcc proposé ici. Mais il y a des différences.

InformationsquelleAutor alecail | 2013-10-04