2016-10-13 1 views
-1

Je suis coincé pendant quelques jours avec un accident sur Crashlytics qui dit:Un danger en utilisant performselector dans objectif-c?

libobjc.A.dylib

objc_msgSend

J'ai réussi à souligner ce qui semble être la raison de ce crash: __NSThreadPerformPerform

Avec une petite recherche sur la pile, il semble être lié à performSelector: withObject: afterDelay:

Le code je mentionne un délai de tout le temps. J'utilise cette méthode pour appeler ce que nous pourrions appeler "functors" dans iOS, en recréant dynamiquement des sélecteurs à partir d'un tableau de chaînes auquel j'accède depuis un état enum.

Et fondamentalement, c'est toutes les informations que j'ai à ce jour, j'ai appris que le afterDelay: rend votre appel retardé au prochain RunLoop. Cela s'applique-t-il aussi à performSelector: withObject: ou afterDelay: ajoute quelque chose à la méthode qui cause cela?

Et, enfin, la vraie question:

est-performSelector withObject: afterDelay: une bonne façon de faire foncteurs, ou est-il dangereux de l'utiliser comme ceci, et dois-je faire autrement?

Merci à l'avance,

+0

Comme tout en Objective-C, le performSelector est sujet aux erreurs pour le développeur et peut provoquer de nombreux plantages de objc_msgSend. Cette erreur est principalement causée par l'appel du sélecteur sur le mauvais objet (l'objet que vous êtes censé appeler est probablement désalloué) –

+0

Oui, mais je suis conscient de ce genre de choses et c'est tout à fait la "manière normale" de planter quand en utilisant des pointeurs. Mais ici je ne vois pas comment mon objet pourrait être désalloué au moment où je l'appelle, et même s'il attend le prochain runLoop comment mon objet pourrait être libéré si je restais sur le même ViewController en utilisant seulement IBOutlet. Cela peut-il être causé par un problème de "mémoire"? L'ARC devrait garder des ressources importantes pour ce cas, n'est-ce pas? –

+0

Essayez d'activer le mode Zombie pour votre système de débogage. Répliquez le crash et il devrait vous dire ce qui ne va pas. –

Répondre

0

Ne pas simplement supposer que votre objet existe toujours et peut effectuer sélecteur. Testez-le avant!

if ([someObject respondsToSelector:@selector(someSelector)]) { 
    [someObject performSelector:@selector(someSelector) withObject:nil]; 
} 
+0

Merci beaucoup, je ne sais pas comment j'ai oublié ce haha. –

+0

Eh bien, l'objet n'existe pas (la variable étant 'nil') n'est pas un problème. L'objet qui n'effectue pas de sélection serait un problème, mais cela indiquerait que l'objet n'est pas ce que le programmeur pense être. – newacct