2009-11-21 7 views
2

Il est vraiment ahurissant de découvrir de nombreuses différences entre l'iPhone et les simulateurs. J'ai passé plusieurs heures à essayer de comprendre pourquoi mon application fonctionnait sur le simulateur mais s'est écrasée sur mon appareil iPhone. Il s'avère que le coupable est triéArrayUsingDescriptors. Y a-t-il plus de choses comme ça? S'il vous plaît partager avec moi.écrasé sur l'iphone mais pas sur le simulateur

Pour partager avec vous sur la question et les correctifs:


code écrasé sur l'iPhone, mais pas simulateur

NSSortDescriptor* aDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"count" ascending:NO] autorelease]; 
NSArray* anNsArray = [[NSArray alloc] init]; 
NSArray* aSortedNsArray = [[NSArray alloc] init]; 

aSortedNsArray = [anNsArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:aDescriptor]]; 

La question est sur [NSArray arrayWithObject:aDescriptor];


Les corrections doivent créer un tableau pour stocker:

NSArray* descriptorArray = [[NSArray alloc] initWithObjects:countDescrp, nil]; 
aSortedNsArray = [anNsArray sortedArrayUsingDescriptors:descriptorArray]; 

Wayne Campbell, CA

Répondre

1
NSSortDescriptor* aDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"count" ascending:NO] autorelease]; 
NSArray* anNsArray = [[NSArray alloc] init]; 
NSArray* aSortedNsArray = [[NSArray alloc] init]; 

aSortedNsArray = [anNsArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:aDescriptor]]; 

Ceci est un mauvais mécanisme d'initialisation, et si l'extrait de code est complet, votre problème se trouve sur l'objet anNsArray qui est vide.

Vous n'avez pas non plus besoin d'initialiser aSortedNsArray.

il devrait donc être:

NSSortDescriptor* sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"count" ascending:NO] autorelease]; 

// Assume you return it as array of objects from a property or method 
NSArray *array = [self objects]; 
NSArray *sortedArray = nil; 
if ([array count] > 0) { 
    sortedArray = [array sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]]; 
} 

// Then you check the sortedArray 
if (sortedArray == nil || [sortedArray count] == 0) 
    [self somethingIsWrong];  

arrayWithObject: (autoreleased) ou initWithObject: (manuel) est juste une façon différente d'allouer objet NSArray. Cela ne causera pas de crash normalement. Parce que ce qui vous intéresse est le classedArray ne conservant pas l'objet tableau descripteurs.

3

Le code affiché ne tombe pas en panne. Bien qu'il y ait quelques objets qui fuient, ils ne se plantent pas sur le simulateur, ni sur l'appareil.

Je pense que votre problème est ailleurs. Essayez de le réduire en utilisant un nouveau projet et copiez uniquement du code suspect.

2

Nikolai,

Il n'a pas écrasé lorsque ma demande était simple et petite. Il peut s'agir d'autorelease et de release comme indiqué dans cet article: http://kosmaczewski.net/2009/01/28/10-iphone-memory-management-tips/ où l'auteur pointe un autre problème similaire:

"Je suis sûr que vous avez rencontré une panne de votre application lors de l'utilisation de dictionaryWithObjects de NSDictionary: forKeys: et puis en découvrant que remplacer cela par initWithObjects: forKeys: a fait fonctionner votre application correctement. "

En utilisant [NSArray arrayWithObject: aDescriptor], NSArray est créé avec autorelease; En revanche, l'utilisation de [[NSArray alloc] initWithObjects: countDescrp, nil] nécessite spécifiquement quand libérer NSArray.

Le simple changement de code a fait que mon application ne plante pas 100% du temps sur l'iphone alors que l'ancien code a fait planter l'application 100% du temps.

+0

Encore: Le code que vous avez posté n'est pas responsable de l'accident que vous avez rencontré. Dans votre question, vous avez déclaré que 'sortedArrayUsingDescriptors' ne fonctionne pas comme prévu sur le périphérique, ce qui est faux. Votre bug est probablement dû à une mauvaise gestion de la mémoire. Il suffit de piquer autour, en commutant 'arrayWithObject:' pour 'initWithObject:' sans comprendre ce qui se passe n'est pas vraiment utile. Mon conseil est: Lire et comprendre le guide de gestion de la mémoire Cocoa: http://developer.apple.com/mac/library/documentation/cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html –

0

Nikolai,

Vous pourriez avoir raison. La plupart des codeurs ont du mal à exclure la possibilité d'une mauvaise gestion de la mémoire en utilisant Objective C. Si jamais je découvre l'autre vrai bogue sous-jacent que vous avez spéculé, je vais mettre à jour ici. Au moment voulu, je rappellerais aux codeurs d'être conscients des différences entre arraywithobjects et initwithobjejcts; Utilisez-les avec sagesse. Merci d'avoir répondu.

Wayne

+0

Les différences entre 'arrayWithObject:' et 'initWithObject: 'sont évidents et bien connus. C'est pourquoi je vous ai indiqué le guide de gestion de la mémoire Cocoa: Tout est là et devrait être considéré comme fondamental pour chaque programmeur Cocoa. –

Questions connexes