Debugger les bugs mémoires
Bonjour,
Je reprends une application développée par un consultant et l'application crashe beaucoup mais pas de manière déterministe. Mon analyse m'amène à penser que ce sont entre autres des bugs mémoires qui causent ces crashes, voilà mes pistes :
1) Un même scénario d'utilisation peut ne pas crasher plusieurs fois de suites et ensuite crashé plusieurs fois de suite.
2) J'ai vu des retain cycles (notamment sur weak/strong self)
3) Des Blocks sont parfois en attributs de classe avec la propriété :
=> @property (nonatomic, strong) Blocky monBlock;
Alors que je vois dans les recommandations, qu'il est conseillé d'utiliser :
=> @property (copy) Blocky monBlock;
4) Je reçois des mémory warning après de nombreux scrolls de tableview.
Au final, voici ma question, comment debugger les bugs mémoires ?
Je suis preneur de vos techniques et astuces pour debugger en général.
A bientôt.
Réponses
Instruments. Et inspection du code à l'oeil nu.
T'as déjà des piste d'après ce que tu dis, essaie de corriger ça et vois ce que ça donne.
Puis changer de consultant à l'avenir pour un qui sait coder et qui teste son code avant de release c'est bien aussi...
Tu peux aussi c/c des bouts de code "suspects" on te donnera un avis.
Et sinon :
- Pour les block copy c'est bien mieux.
- Ils disent quoi exactement ces memory warning ?
Je conseillerais également Instruments.
Il faut également voir s'il y a essentiellement des fuites mémoires, ou des juste trop d'allocations inutiles, c'est deux problèmes différents. L'un concerne de l'optimisation (genre, si t'as une énorme application consommatrice de ressources), l'autre concerne des problèmes de conception.
Je conseillerais également Analyze, qui peut te donner quelques pistes (en plus de " l'oe“il nu ").
Salut Pyroh et Larme, merci pour vos conseils. Au sujet de Instruments, je l'utilise déjà pour voir les allocations de mémoires.
Pouvez-vous me précisez votre point de vue sur l'utilisation d'Instruments dans mon cas ?
@Pyroh, dans la méthode didReceiveMemoryWarning, je mets juste un NSLog. Comment avoir plus de détails ?
@amadeh : Utilise la partie Memory Leaks d'Instruments.
Utiliser Instruments à l'aveugle peut te faire perdre du temps.
Commence par passer un coup de build&analyze comme conseillé par Larme pour évacuer les problèmes les plus simples.
@Larme : l'idée du Analyse m'a permis de faire ressortir quelques leaks, merci
Mais ça bugge encore beaucoup. En quelques minutes, deux crashes, en voici un :
Dans le cellForRowAtIndexPath dans la méthode dequeueReusableCellWithIdentifier
* thread #1: tid = 0xcd801, 0x35752c6e libobjc.A.dylib`realizeClass(objc_class*) + 26, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
frame #0: 0x35752c6e libobjc.A.dylib`realizeClass(objc_class*) + 26
frame #1: 0x35752d30 libobjc.A.dylib`realizeClass(objc_class*) + 220
frame #2: 0x35755ffc libobjc.A.dylib`lookUpImpOrForward + 156
frame #3: 0x35755f56 libobjc.A.dylib`_class_lookupMethodAndLoadCache3 + 34
frame #4: 0x3575c1d8 libobjc.A.dylib`_objc_msgSend_uncached + 24
frame #5: 0x2ae84554 QuartzCore`CA::Layer::contents_visibility_changed(CA::Transaction*, bool) + 48
frame #6: 0x2ae834d6 QuartzCore`CA::Layer::mark_visible(CA::Transaction*, bool) + 186
frame #7: 0x2ae834aa QuartzCore`CA::Layer::mark_visible(CA::Transaction*, bool) + 142
frame #8: 0x2ae834aa QuartzCore`CA::Layer::mark_visible(CA::Transaction*, bool) + 142
frame #9: 0x2ae887ba QuartzCore`CA::Layer::update_removed_sublayer(CA::Transaction*, unsigned int) + 22
frame #10: 0x2ae895f8 QuartzCore`CA::Layer::remove_sublayer(CA::Transaction*, CALayer*) + 76
frame #11: 0x2ae89586 QuartzCore`CA::Layer::remove_from_superlayer() + 94
frame #12: 0x2b46a656 UIKit`-[UIView(Internal) _addSubview:positioned:relativeTo:] + 958
frame #13: 0x2b4811a4 UIKit`-[UIView(Hierarchy) insertSubview:atIndex:] + 36
frame #14: 0x2b5294cc UIKit`-[UITableView _addContentSubview:atBack:] + 268
frame #15: 0x2b58f678 UIKit`__53-[UITableView _configureCellForDisplay:forIndexPath:]_block_invoke + 2260
frame #16: 0x2b470a04 UIKit`+[UIView(Animation) performWithoutAnimation:] + 72
frame #17: 0x2b58ed9c UIKit`-[UITableView _configureCellForDisplay:forIndexPath:] + 336
frame #18: 0x2b5c6b0e UIKit`-[UITableView dequeueReusableCellWithIdentifier:forIndexPath:] + 282
Pour les EXC_BAD_ACCESS, NSZombies devrait t'aider.
En général, tu essayes d'accéder à un objet qui a été désalloué.
J'ai mis en place NSZombie dans XCode et j'ai activité la détection des NSZombies dans Instruments ainsi que l'enregistrement des couts reference.
L'application crashe encore mais Instruments ne me remonte rien.