2010-07-23 5 views

Répondre

6

Attention! Vous êtes sur le point d'entrer une magie assez profonde dans ObjC, et les types de bogues que vous pouvez générer sont hallucinants. Ce sont les dernières techniques que vous devriez utiliser après que tout le reste a échoué, et vous devriez faire tout ce que vous pouvez pour isoler ce code. Cela dit, ObjC est un langage hautement dynamique, et vous pouvez recâbler la plupart des choses. Tout d'abord, à votre question spécifique, vous pouvez changer la classe d'une instance, ce qui permettra d'atteindre ce que vous voulez. Les règles sont essentiellement:

  • La nouvelle classe devrait être une sous-classe de l'ancienne classe
  • La nouvelle classe ne doit pas ajouter de Ivars. L'ajout d'ivars dans la sous-classe est l'une des choses qui peuvent mener aux bugs de l'esprit mentionnés ci-dessus.

Vous n'obtiendrez pas d'avertissements ou d'erreurs si vous faites ce problème. Vous aurez juste des accidents bizarres.

Étant donné que, en changeant la classe d'un objet est en fait très simple:

object->isa = [NewClass class]; 

Au-delà, vous pouvez modifier la mise en œuvre d'une méthode pour chaque instance d'une classe à l'aide de la méthode swizzling. J'ai quelques exemples de ceci dans Hijacking with method_exchangeImplementations(). Bonne chance d'utiliser le débogueur une fois que vous avez fait cela, cependant.

+0

Merci pour cela. C'est fascinant, mais cela m'a convaincu de m'en tenir à mes forces et d'éviter cela à tout prix. –

+0

En fait, ne semble pas trop mauvais, en fait pourrait bien fonctionner dans mon cas. –

+1

Utilisé avec soin, c'est en fait très simple. Faites tout ce que vous pouvez pour vous assurer que le reste de votre programme ne s'en soucie pas. Cela fait partie de la façon dont KVO est mis en œuvre. La première fois que vous observez un objet avec KVO, sa classe passe à une sous-classe magique KVO qui modifie tous les accesseurs. Tout fonctionne bien, et vous ne remarquez même pas; mais je suis sûr que déboguer le code KVO * lui-même * est un divertissement au mieux. Pareil avec ton problème; documentez-le très bien ou vous ne vous souviendrez jamais de ce que vous faisiez. –

1

En fait, vous pouvez modifier n'importe quoi avec un sous-classement. C'est une des choses les plus délicates que vous pouvez faire, et vous pouvez regarder dans swizling de méthode à la place (mais la méthode swizling affectera tous les membres de la classe), mais dans l'objectif c, il est super facile de définir la classe de n'importe quel objet. Tout ce que vous avez à faire est de déclarer une sous-classe qui ne déclare pas d'ivars supplémentaire, et remplace seulement les méthodes dont vous avez besoin (et vous voulez probablement appeler la super implémentation), puis changez la classe d'un objet à l'exécution via object_setClass (déclaré dans).

+0

Merci, ça aide. –

Questions connexes