2010-01-24 5 views
0

J'ai un problème de déroutement lorsque j'essaie de remplir un NSMutableArray avec UIImages.Problème lors du remplissage de NSMutableArray avec des objets UIImage

CGBitmapInfo bitmapInfo = kCGBitmapByteOrderMask; 
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault; 
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 

while(...)  // <--- Iterates through data sets 
{ 

      CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, data, numBytes, NULL); 
      CGImageRef cImage = CGImageCreate(iw, ih, 8, 32, 4 * iw, colorSpace, bitmapInfo, provider, NULL, NO, renderingIntent); 
      UIImage *finalImage = [UIImage imageWithCGImage:cImage]; 


      [images addObject:finalImage]; // <--- Declared and instantiated earlier 

      [delegate sendImage:finalImage]; 

      CGImageRelease(cImage); 
      CGDataProviderRelease(provider); 
} 

CGColorSpaceRelease(colorSpace); 

[delegate operationCompletedWithImages:images]; 

C'est ainsi que j'ai le code en cours d'exécution. J'ai donc essentiellement une fonction qui s'exécute dans l'instruction while qui renvoie l'ensemble de données bitmap suivant, puis je crée un UIImage et le stocke dans le tableau mutable.

J'ai testé cela en écrivant chaque fichier sur le disque puis en y accédant, ce qui donne le bon ensemble d'images. Le problème est lorsque vous utilisez le tableau pour garder les données en mémoire, en accédant à n'importe quel objet image dans le tableau, je reçois la même image exacte encore et encore. L'image est également toujours la dernière image de l'ensemble.

J'ai essayé de tester le contenu en définissant le tableau comme un tableau d'animation UIImageView et en utilisant un NSTimer pour faire défiler le contenu. De toute façon, c'est juste la même image (la dernière image tirée) encore et encore.

Cette opération s'exécute à l'intérieur d'un objet NSOperation sous-classé afin de ne pas bloquer l'interface. Un autre aspect intéressant ici est que lorsque le tableau d'images envoyé avec operationCompletedWithImages me donnait le tableau d'images en double, j'ai essayé d'utiliser le message sendImage et de stocker les images dans un tableau différent à l'intérieur de l'objet délégué (en pensant que c'était un threading problème). Cela m'a donné les mêmes résultats.

J'ai été bloqué sur cela pendant plus d'une semaine sans progrès. Je n'ai jamais rien vu de tel et je ne peux pas trouver quelqu'un d'autre qui a eu un problème similaire. Je serais heureux de fournir des informations supplémentaires si quelqu'un pense que cela aiderait à résoudre ce problème.

Si quelqu'un pouvait fournir une assistance, je l'apprécierais grandement.

Répondre

0

Compris le problème. Il s'est avéré être un problème avec le support données pointeur.

Où avant j'accédais données chaque fois que je pensais qu'il serait itérer et écraser avec de nouveaux contenus, et le nouveau contenu serait branché sur mon CGDataProviderRef. Ce n'était pas le cas, j'ai fini par fournir un pointeur vers les mêmes données de support pour le fournisseur. La solution consistait à copier les données dans un objet NSData et à utiliser cette copie pour DataProvider.

Ainsi, au lieu de:

CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, data, numBytes, NULL); 

Il serait:

NSData *pxData = [[NSData alloc] initWithBytes:pFrameRGB->data length:numBytes]; 
CGDataProviderRef provider = CGDataProviderCreateWithCFData((CFDataRef)pxData); 
0

Vous ne savez pas si c'est le problème, mais vous devez probablement notifier votre délégué des modifications sur le thread principal, pas le thread sur lequel s'exécute NSOperation.

[delegate performSelectorOnMainThread:@selector(sendImage:) withObject:finalImage waitUntilDone:YES]; 

De même pour le dernier message. Si le délégué modifie quelque chose lié à UIKit, doit être être invoqué sur le fil principal!

+0

Merci! C'est certainement un pas dans la bonne direction. Lorsque j'effectue le sélecteur sendImage sur le fil principal, je reçois définitivement les images appropriées. Maintenant, j'ajoute ces images à un tableau dans l'objet délégué (thread principal). Le problème est qu'une fois qu'ils sont tous ajoutés et j'essaie de les revoir, ils sont tous les mêmes. Très étrange. Donc, je reçois les images appropriées du thread d'arrière-plan, mais en quelque sorte le tableau ne fait que stocker des copies de la dernière image reçue ... –

+0

Que voulez-vous dire par «tout de même»? Est-ce que toutes les images ont le même contenu, ou sont-elles exactement la même instance *? Vérifiez les valeurs de pointeur étant stockées dans votre tableau! – PfhorSlayer

+0

Les rendus sont identiques. La chose intéressante est que, bien que les pointeurs UIImage & CGImageRef soient uniques dans le tableau, l'adresse NSObject -> ISA pour chaque UIImage dans le tableau est la même. Je ne sais pas ce que cela signifie, mais c'est la seule connexion que j'ai pu trouver jusqu'à présent. J'ai également essayé de déclarer 10 variables d'instance UIImage et d'y stocker un ensemble de dix images. Cela a fonctionné! Donc, le problème semble se produire uniquement lorsque vous stockez les images dans un tableau (j'ai essayé un NSArray, CFArray, et C tableau - UIImage * images [...]). –

0

On pourrait supposer que NSMutableArray gérerait la gestion de la mémoire de l'objet qui y est ajouté, mais peut-être parce que vous avez affaire aux assistants Quartz de niveau C/Core wrappers, ce n'est peut-être pas le cas.

Dans d'autres méthodes de manipulation d'images que j'ai expérimentées, elles sont généralement enveloppées dans un pool d'autorelease si elles sont impliquées dans des threads.

Avez-vous essayé d'expérimenter avec release/autorelease sur l'image finale?

+0

J'ai joué avec la modification des comptes de retenue en vain. Je pensais que c'était un coup dans le noir de toute façon car je ne pouvais pas comprendre pourquoi cela causerait les objets en double dans le tableau. Ce qui me fait vraiment tourner la tête - dans l'objet délégué (sur le thread principal) j'ai essayé de tirer un CGImageRef de chaque UIImage comme ils ont été envoyés via sendImage et d'allouer un nouveau UIImage avec le CGImageRef pour obtenir une nouvelle copie avant ajouter au tableau. J'obtiens toujours un tableau de la même image encore et encore (toujours la dernière image ajoutée). –