2010-04-07 4 views
1

Je travaille sur une application iPhone en ce moment et je suis aux prises avec de l'animation. Fondamentalement, j'ai 109 cadres pour faire glisser sur un homme à l'écran, donc ce que je fais est à l'écoute des touches, et de calculer les cadres que je dois passer à.Animation iPhone basée sur le toucher

Cela fonctionne très bien, mais après un certain temps, je reçois une fuite de mémoire et l'application se bloque. Je charge toutes les images dans et Array au démarrage, et en utilisant un UIImageView pour afficher les images. Les images sont chargées en utilisant imageWithContentsOfFile:.

Quelle est la meilleure façon de faire cela?

Heres une partie du code source:

- (void)viewWillAppear:(BOOL)animated { 
animationQueue = [[NSMutableArray alloc] initWithObjects:0]; 
imageArray = [[NSMutableArray alloc] initWithObjects:nil]; 
for(int i = 1;i<110;i++) 
{ 
    [imageArray addObject:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat: @"%i", i] ofType:@"png"]]]; 
} 
[super viewWillAppear:animated];} 

Voir Est-ce que le code de charge:

- (void)viewDidLoad { 
animation = [[UIImageView alloc] initWithFrame: CGRectMake(0, 0, 480, 320)]; 
animation.contentMode = UIViewContentModeCenter; 
[self.view addSubview:animation]; 
animation.image = [imageArray objectAtIndex:40]; 
[super viewDidLoad];} 

Touches Handler:

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 
// Enumerates through all touch objects 
for (UITouch *touch in touches) { 
    CGPoint touch_point = [touch locationInView:self.view]; 
    // calculate which frame to end on 
    int pos = ceil((touch_point.x/480) * 108); 
    [self redrawAnimation:pos]; 
}} 

Redessiner Animation:

- (void)redrawAnimation:(int)end_frame { 
    animation.image = [imageArray objectAtIndex:end_frame]; 
} 

L'application se bloque lorsque vous faites glisser votre doigt le long de l'écran plusieurs fois.

+0

pouvez-vous poster un peu de votre code, et dites-nous le point, sur lequel votre crash de l'application? – schaechtele

+0

L'application se bloque lorsque vous faites glisser votre doigt le long de l'écran plusieurs fois. – user310729

Répondre

0

N'est-ce pas un problème d'allocation de trop de mémoire? 110 images pourraient en prendre trop. Que diriez-vous d'un changement:

- (void)redrawAnimation:(int)end_frame { 
    animation.image = [imageArray objectAtIndex:end_frame]; 
} 

à:

- (void)redrawAnimation:(int)end_frame { 
    animation.image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] 
            pathForResource:[NSString stringWithFormat: @"%i", end_frame] 
               ofType:@"png"]]]; 
} 

et ne pas les images dans Préallouer - (void) viewWillAppear: (BOOL) animée.

Je sais, ce serait beaucoup plus lent, mais si c'est un cas de limite de mémoire, vous n'avez pas d'autre choix. Vous pouvez également essayer de ne préallouer qu'une partie d'une séquence, mais il se peut que le tampon soit affamé si vous animez les images plus rapidement qu'elles ne le seraient.

+0

Merci! Fonctionne beaucoup mieux sans précharger les images, et a toujours l'effet désiré. – user310729

0

Est-il possible que votre position int ait parfois une valeur pour laquelle il n'y a pas d'index dans le tableau?

Je veux dire ces lignes:

int pos = ceil((touch_point.x/480) * 108); 
[self redrawAnimation:pos]; 

Quel est le message d'erreur du débogueur, si les application se bloque?

0

Vous ne dites pas quel est le crash réel, ce qui peut être un indice important. Mais je suis prêt à deviner, en fonction de la taille de vos bitmaps, que vous gardez trop de mémoire.

UIImage est généralement assez intelligent dans les coulisses. Par exemple. Dans votre vueWillAppear, bien que vous créiez 110 références d'image, il ne charge probablement pas les fichiers avant d'en avoir besoin. Quand vous déplacez votre doigt autour d'un groupe, pensez-vous que c'est ce qu'il faut pour réellement invoquer/charger tous les cadres? Il se pourrait que vous atteigniez une limite quelque part sur le chemin de cela? UIImage est également connu pour vider intelligemment les données bitmap dans des situations de mémoire faible, mais c'est un peu une boîte noire à l'appelant.

Découvrez exactement où l'application se bloque. Pensez également à exécuter des Instruments pour profiler l'utilisation de la mémoire et autres joyeusetés. Ce pourrait être quelque chose qui ne soit pas du tout lié à la mémoire (un bug ailleurs dans votre code?). Ou essayez d'utiliser la moitié ou le quart du nombre d'images, etc., pour voir ce qui se passe. S'il s'avère qu'il s'agit d'une gestion des ressources, vous aurez un contrôle plus précis si vous gérez la mémoire de manière explicite en créant et en libérant des UIImages à la volée (ou en mode de préchargement fenêtré/par lots) ou consultez Cocos2D ou même OpenGL brut pour les sprites/textures appropriées, où le contrôle sur ce genre de choses est beaucoup plus accessible (au prix de beaucoup plus de plomberie.)