2009-10-11 3 views
3

Est-ce qu'un Cocoahead peut expliquer pourquoi UIView et ses sous-classes n'adoptent pas le protocole NSCopying?Pourquoi UIView (ou ses sous-classes) n'adopte-t-il pas le protocole NSCopying?

Je peux voir, philosophiquement, pourquoi UITouch ne serait pas conforme à la copie, car c'est un objet très temporel. Par UIView, et ses sous-classes, en particulier UIButton, semblent être devrait être capable d'être copié.

Certes, Apple a de bonnes raisons de faire les choses comme ils le font. Connaissez-vous leur raison?

+0

Dans quelles circonstances avez-vous besoin de copier une vue? – Abizern

+0

Cette question est seulement informative..Toutefois, pour répondre à votre question le problème qui a déclenché ma question était celui avec UIButtons. J'ai eu un UIButton qui était presque exactement comme un autre bouton. Je voulais donc copier le premier bouton dans le second. puis modifiez simplement les quelques différences. – SooDesuNe

Répondre

4

Il semblerait que la question qu'ils ont posée n'était pas "Pourquoi pas?" mais "Pourquoi le faire?" Il y a peu de raison de le faire. Il est rarement nécessaire de copier une vue en direct. Habituellement, les vues de modèle sont créées via le protocole NSCoding (c'est-à-dire avec Interface Builder), et c'est à peu près tout ce qu'une vue copiable serait bon pour.

+3

Un bon exemple de lorsque vous souhaitez effectuer plusieurs copies d'un objet, comme une vue, est dans UITableView lors de la création de la douzaine de cellules réutilisables. Pouvoir en copier un est beaucoup plus facile que de multiples allocations de UIViews/UIButtons/UILabels, etc. – mahboudz

+1

Par exemple, j'ai créé une pièce d'échecs via une sous-classe UIView dans IB. Maintenant, je veux cloner cette vue pour toutes les pièces d'échecs similaires. Mettre chaque pièce dans son propre fichier NIB semble juste un peu stupide (et inefficace). La chose * évidente * à faire est ce que l'OP a suggéré, mais il ne semble pas y avoir de moyen simple de cloner UIView. – wcochran

+1

@wcochran: Rien ne vous empêche de créer une sous-classe UIView qui implémente le comportement que vous voulez, si c'est important pour vous. Exiger que chaque classe de vue écrit pour implémenter la copie juste parce que vous n'aimez pas les plumes serait stupide et inefficace. – Chuck

4

Question intéressante. En plus de la réponse de Chuck, je voulais ajouter que la raison en est peut-être parce qu'Apple a pris cette décision de conception ... C'est aussi simple que ça; pas de vraie raison spécifique mais c'était la décision prise.

Je peux aussi supposer que cette décision aurait pu être prise parce que UIView est utilisé comme une sous-classe pour quelques autres classes et les ingénieurs ne voulaient pas imposer NSCopying avec force sur les sous-classes.

3

Parce que NSCopying n'est pas très bon pour les copies profondes (récursives) de graphiques d'objets. Par exemple, [NSArray copy] copie la liste des objets, pas les objets eux-mêmes. Les graphiques d'objets sont mieux servis par NSCoding. Ce qui dans une heureuse coïncidence est pris en charge par UIView.

Si vous souhaitez copier une vue personnalisée avec des propriétés, vous devez prendre en charge NSCoding. Par exemple,

@interface SKCustomCell : UITableViewCell 

@property (strong, nonatomic) IBOutlet UILabel* nameLabel; 
@property (strong, nonatomic) IBOutlet UIView* topView; 

@end 


static NSString* propertiesKey = @"SKCustomCellProperties"; 

@implementation SKCustomCell 

@synthesize nameLabel; 
@synthesize topView; 

- (id) initWithCoder:(NSCoder *)aDecoder 
{ 
    self = [super initWithCoder: aDecoder]; 
    [self setValuesForKeysWithDictionary: [aDecoder decodeObjectForKey: propertiesKey]]; 
    return self; 
} 

- (void) encodeWithCoder:(NSCoder *)aCoder 
{ 
    [super encodeWithCoder: aCoder]; 

    [aCoder encodeObject: [self dictionaryWithValuesForKeys: [[NSArray alloc] initWithObjects: @"nameLabel", @"topView", nil] forKey: propertiesKey]; 
} 


@end 
+0

Il est intéressant de savoir que UIVIews implémente le NSCoding, mais cela ne correspond pas à la réponse à la question. –

+1

@ Mark, je pense que je l'ai fait. Les classes qui adoptent NSCopying semblent faire des copies superficielles par convention. Une copie superficielle d'un UIView n'est généralement pas utile. Une copie en profondeur ne serait pas pratique, car toutes les propriétés de chaque sous-classe UIView devraient prendre en charge NSCopying. –

Questions connexes