2009-10-03 10 views
4

En Objective-C, j'ai une catégorie pour une classe:Comment appeler la fonction d'origine de la fonction surchargée dans une catégorie?

@interface UILabel(CustomInit) 

- (id)initWithCoder:(NSCoder *)coder; 

@end 

Ce que je fais est d'écrire une fonction d'initialisation personnalisée qui fait des choses supplémentaires, et ce que je voudrais faire, est en cette fonction d'initialisation personnalisée appelle la base initWithCoder de UILabel. Est-ce possible? Comment?

EDIT

Merci. Ok, donc mes plans sont discutables. Impossible de surcharger initWithCoder. Existe-t-il un moyen d'obtenir la même fonctionnalité (où tous les UILabels obtiennent cette étape d'initialisation ajoutée) sans surcharger initWithCoder? Ou peut-être y a-t-il un exemple de code pour le initWithCoder de UILabel que je peux simplement réécrire avec le code ajouté?

EDIT

Ok, donc d'être clair sur ce que je suis en train:

Can I embed a custom font in an iPhone application?

a une réponse dans laquelle quelqu'un ajoute manuellement une police personnalisée sur l'iPhone en utilisant le privé Fonction GraphicServices GSFontAddFromFile. J'ai essayé ce code et cela a bien fonctionné pour définir manuellement la police d'une étiquette. Toutefois, si vous essayez de définir la police dans Interface Builder, elle ne se charge pas correctement, elle descend simplement à la police système. Ce que je voulais faire était charger la police manuellement et définir la police de l'étiquette automatiquement avec la police choisie dans IB. De cette façon, je n'ai pas besoin de faire un exutoire pour chaque étiquette que je pose. Je n'ai pas non plus besoin d'écrire une sous-classe d'étiquette ridicule (qui a également été suggérée dans ce fil et fait une grande quantité de dessin personnalisé) que j'ai trouvé plutôt grotesque. Maintenant, je pourrais encore faire une sous-classe pour toutes mes étiquettes, mais il y a aussi le cas des étiquettes incorporées dans d'autres objets de l'interface utilisateur, à savoir les UIButtons. J'aimerais que les étiquettes incorporées ne soient pas non plus brisées.

Toutes les suggestions seraient super. Merci.

+0

Quelle est cette initialisation par étiquette que vous devez faire? Peut-être pouvons-nous suggérer une alternative. –

+3

(An aside) Ne remplacez jamais les méthodes existantes dans les classes fournies par Apple avec des catégories. Vous n'avez aucun moyen de connaître les détails de l'implémentation interne/dépendances ... – bbum

Répondre

1

Comment vous en pensez-vous? Saisissez l'adresse de méthode d'origine pour initWithCoder lors de l'exécution et stockez-la dans une variable statique. Faire une méthode de swizzle pour remplacer l'implémentation des classes avec mon initWithCoder. Et puis dans mon initWithCoder, j'appellerais la méthode originale stockée dans la variable statique.

Vous pouvez le mettre dans une catégorie et appeler cette étape d'initialisation de classe au début du programme, en s'assurant qu'il ne peut pas être appelé deux fois, ou s'il ne fait rien.

Cela semble dangereux, mais je pense que ça devrait marcher.

+4

Mauvaise idée; dangereux. Assez bon à des fins de débogage, mais ne l'expédie pas dans le code de production car, en fin de compte, il vous hantera. – bbum

+0

Quels problèmes pensez-vous qu'il peut causer? – kidnamedlox

13

De l'Mac OS X Reference Library:

Lorsqu'une catégorie remplace une méthode héritée , la méthode dans la catégorie peut, comme d'habitude, invoquer la mise en œuvre héritée par un message au super. Toutefois, si une catégorie remplace une méthode qui existait déjà dans la classe de la catégorie, il est impossible d'appeler pour implémenter l'implémentation d'origine.

+0

J'ai ajouté un peu d'accent sur votre réponse, et j'ajouterai ici que 'initWithCoder:' est certainement implémenté par UILabel lui-même, ce qui signifie " existait déjà dans la classe de la catégorie ". –