La suppression de “'...' est obsolète” lors de l'utilisation de respondsToSelector
Je suis appui 10.4+ en choisissant la plus actuelle de l'API, au moment de l'exécution:
if ([fileManager respondsToSelector:@selector(removeItemAtPath:error:)])
[fileManager removeItemAtPath:downloadDir error:NULL];
else
[fileManager removeFileAtPath:downloadDir handler:nil];
Dans ce cas, 10.5 et utilisera removeItemAtPath:error:
et 10,4 utilisera removeFileAtPath:handler:
. Super, mais j'ai toujours les avertissements du compilateur pour les vieilles méthodes:
warning: 'removeFileAtPath:handler:' is deprecated [-Wdeprecated-declarations]
Est-il une syntaxe de if([… respondsToSelector:@selector(…)]){ … } else { … }
qui laisse le compilateur Clang) de ne pas avertir sur cette ligne?
Si non, est-il un moyen de tag que la ligne sera ignorée pour -Wdeprecated-declarations
?
Après avoir vu certaines réponses, permettez-moi de préciser que la confusion entre le compilateur en ne sachant pas ce que je fais n'est pas une solution valable.
Vous devez vous connecter pour publier un commentaire.
J'ai trouvé un exemple dans le Compilateur Clang Manuel de l'Utilisateur qui me permet d'ignorer l'avertissement:
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
et puis#pragma clang diagnostic warning "-Wdeprecated-declarations"
si Clang sur OS X ne supporte paspush
?Vous pouvez déclarer un fichier séparé qui est désigné pour l'appel de méthodes obsolètes et de définir le fichier par les drapeaux de compilation dans Xcode pour ignorer
-Wdeprecated-declarations
. Vous pouvez ensuite définir une fonction factice dans ce fichier pour appeler les méthodes obsolètes, et d'éviter ainsi les mises en garde dans votre vraie source des fichiers.-compatibility*
méthodes de catégories sur les classes en question (par exemple,-[NSFileManager compatibleRemoveItemAtPath:]
).Je ne suis pas sûr si le bruit est assez intelligent pour l'intercepter, mais si elle ne l'est pas, vous pouvez essayer d'utiliser
performSelector:withObject:withObject:
ou de bâtiment et de l'invocation d'une NSInvocation objet.Vous pourriez jeter
fileManager
à unid
—ids
sont en mesure de se référer à toute Objective-C objet, de sorte que le compilateur n'est pas censé vérifier les méthodes qui sont appelées l'une:ne devrait pas soulever des avertissements ou des erreurs.
Bien sûr, cela soulève d'autres problèmes, à savoir, vous perdez tous au moment de la compilation de la vérification pour les méthodes appelées sur le
id
. Donc, si vous avez mal orthographié vous le nom de la méthode, etc, il ne sera pas pris jusqu'à ce que la ligne de code est exécutée.Si vous envisager toute forme de "confusion", le compilateur être une solution non valide, vous allez probablement avoir à vivre avec l'avertissement. (Dans mon livre, si vous vous demander comment se débarrasser d'un avertissement, il n'est pas judicieux de regarder un cheval de cadeau dans la bouche et de dire quelque chose n'est pas valide simplement parce qu'il ne regarde pas comme vous le souhaitez.)
Les réponses que le travail au moment de l'exécution impliquent de masquage de l'opération qui se passe avec répartition dynamique de sorte que le compilateur ne se plaignent pas du type d'appel obsolète. Si vous n'aimez pas cette approche, vous pouvez désactiver l'option "Avertir à Propos Obsolète Fonctions" dans votre projet Xcode ou les paramètres de la cible, mais c'est généralement une mauvaise idée. Vous voulez savoir sur l'Api obsolète, mais dans ce cas, vous voulez l'utiliser sans avertissement. Il y a le facile et le difficile façons de le faire, et les chances sont que vous considéreriez comme tous les "non valide" dans une certaine forme, mais cela ne les empêche pas d'être efficace, même correcte. 😉
Un moyen possible d'éviter les mises en garde pourtant toujours sélectionner au moment de l'exécution est d'utiliser
objc_msgSend()
directement:C'est ce que l'Objective-C runtime sous les couvertures de toute façon, et devrait atteindre le résultat que vous voulez avec un minimum de tracas. Vous pouvez même laisser la ligne d'origine, a commenté ci-dessus pour plus de clarté. Je sais que dit la documentation, ", Le compilateur génère des appels à la fonction de messagerie. Vous ne devriez jamais l'appeler directement dans le code que vous écrivez." Vous seul avez à décider quand il est d'accord pour contourner les règles.
performSelector:withObject:withObject:
ouobjc_msgSend()
sont peu perturbateur des approches toujours communiquer votre sens et éviter l'avertissement. Java a des annotations pour supprimer les avertissements, mais C n'est pas. La poisse, mais la vie continue. Je ne suis pas la défense de l'état actuel des choses comme la façon dont il devrait être, ce qui suggère que si vous allez réellement utiliser la langue, il est plus efficace d'embrasser ses bizarreries que d'être élitiste.[<OBJECT> respondsToSelector:@selector(<ALTERNATIVE>))]
.id
, même de vérifier que vous parlez à un objet) ou la manière dont le code se compile (appelperformSelector:withObject:withObject:
est fonctionnellement différent de l'appel de la méthode directement). S'il est impossible d'annoter une ligne sera ignoré pour un avertissement, c'est un problème avec le compilateur. Il devrait être mis en place et corrigé, pas embrassé.id
juste pour éviter les mises en garde. Cependant, à de fausses mises en garde ont tendance à me distraire plus qu'un occasionnel hack, surtout quand j'ai des tests unitaires pour vérifier que le code fonctionne correctement. 🙂 FWIW, je suis d'accord sur la ligne d'avertissement de suppression.