2010-01-05 5 views
1

J'ai une exigence pour créer des objets objets NSDecimalNumber dans le cadre de mon application (car j'ai besoin de la précision du calcul qu'ils offrent) mais je note que dans les calculs ils retournent des objets NSDecimalNumber qui sont, probablement, autoreleased.Création d'objets autorelease dans le développement iPhone

Ma question est vraiment de savoir si cela est potentiellement problématique dans une application iPhone où je peux effectuer beaucoup de calculs. La question ne concerne pas seulement NSDecimalNumber, mais la création parfois inévitable d'objets auto-libérés au cours du développement d'une application iPhone.

Toutes les réponses détaillées sur ce point seraient les bienvenues.

Répondre

7

Oui, ce qui crée beaucoup de cas autoreleased sur l'iPhone peut créer des problèmes de mémoire, en particulier dans une boucle serrée, c'est pourquoi j'ai tendance à les éviter quand je peux. Vous pouvez créer vos propres pools d'autorelease pour gérer cela, mais ils ajoutent également une surcharge de performances et du code supplémentaire dont vous devez tenir compte.

C'est pour cette raison que lorsque je fais des calculs de haute précision, j'ai tendance à utiliser la structure C NSDecimal au lieu de NSDecimalNumbers. En fait, je fis quelques repères sur ce point et trouvé une augmentation significative de la performance en allant avec le struct C (copié de ma réponse here):

NSDecimal 

Additions per second: 3355476.75 
Subtractions per second: 3866671.27 
Multiplications per second: 3458770.51 
Divisions per second: 276242.32 

NSDecimalNumber 

Additions per second: 676901.32 
Subtractions per second: 671474.6 
Multiplications per second: 720310.63 
Divisions per second: 190249.33 

Comme vous pouvez le voir, il y a une augmentation de presque cinq fois la vitesse de calcul entre les chemins NSDecimal et NSDecimalNumber. La plus grande différence entre les calculs NSDecimal et NSDecimalNumber était l'allocation de mémoire des instances NSDecimalNumber. Par conséquent, vous devriez éviter d'allouer des instances de libération automatique temporaires partout où vous le pouvez.

+0

Merci pour votre réponse. J'aime cette réponse et la suggestion par Dave DeLong d'utiliser les piscines autorelease (je souhaite que je pourrais accepter les deux).Je ne suppose pas que je pourrais imposer et demander si vous avez un lien vers le NSDecimal étant utilisé car j'ai trouvé des ressources rares en faisant référence jusqu'ici. – Urizen

+0

Bien qu'il puisse être difficile d'analyser, compte tenu de la complexité de la structure, nous avons récemment basculé tous les calculs de l'infrastructure Open Source Core Plot vers NSDecimal. Le code source peut être téléchargé à partir du référentiel Google Code: http://code.google.com/p/core-plot/. En particulier, regardez le fichier CPUtilities.m pour certaines fonctions d'aide que nous avons construites autour de NSDecimal: http://code.google.com/p/core-plot/source/browse/framework/Source/CPUtilities.m –

+0

Merci vous pour l'aide. Ceci est exactement ce que je cherchais. – Urizen

0

Chaque objet auquel un fragment de mémoire est destiné devra y renoncer. La question est quand.

J'essaie de alloc/init/release quand je le peux, afin que les objets ne traînent que le temps nécessaire.

Si j'utilise autorelease, j'ai moins de contrôle sur le moment où l'objet est libéré. Si l'application tente d'accéder à un objet publié, il peut se bloquer. La gestion de la mémoire est donc une bonne chose, je pense.

Tant que vous conservez des objets auto-libérés renvoyés par une méthode, cela devrait fonctionner. (À moins que vous demandez quelque chose d'autre, dans ce cas, je présente mes excuses à l'avance.)

8

Rappelez-vous, vous pouvez créer vos propres objets NSAutoreleasePool.

Par exemple:

for (int i = 0; i < 1000; ++i) { 
    NSAutoreleasePool * p = [[NSAutoreleasePool alloc] init]; 
    for (int j = 0; j < 1000; ++j) { 
    NSString * s = [NSString stringWithFormat:@"%d,%d", i, j]; 
    NSLog(@"%@", s); 
    } 
    [p release]; 
} 

Si vous faites cela, vous aurez jamais plus de 1000 de ces chaînes en mémoire à la fois.

3

Si vous êtes inquiet au sujet de la manipulation trop d'objets autoreleased vous pouvez créer votre propre piscine autorelease (voir memory management):

for (count = 0; count < limit; count++) 
{ 
    NSAutoreleasePool *loopPool = [[NSAutoreleasePool alloc] init]; 
    NSString *fileContents; 
    NSString *fileName; 

    fileName = [args objectAtIndex:count]; 
    fileContents = [[[NSString alloc] initWithContentsOfFile:fileName] autorelease]; 
    // this is equivalent to using stringWithContentsOfFile: 

    /* Process the file, creating and autoreleasing more objects. */ 

    [loopPool release]; 
}