Почему UIView (или его подклассы) не принимает протокол NSCopying? - PullRequest
3 голосов
/ 12 октября 2009

Может ли Cocoahead объяснить, почему UIView и его подклассы не принимают протокол NSCopying?

С философской точки зрения я понимаю, почему UITouch не будет копировать, поскольку это очень временный объект. По UIView и его подклассам, особенно UIButton, кажется, что они должны быть в состоянии скопировать.

Конечно, у Apple есть веские причины для того, чтобы поступать так, как они. Вы знаете их причину?

Ответы [ 3 ]

4 голосов
/ 12 октября 2009

Интересный вопрос. В дополнение к ответу Чака я хотел добавить, что причина, возможно, в том, что Apple приняла это дизайнерское решение ... Просто так; никакой конкретной причины, но это было принято.

Я также могу постулировать, что это решение могло быть принято, потому что UIView используется в качестве подкласса для нескольких других классов, и инженеры не хотели принудительно навязывать NSCopying подклассам.

4 голосов
/ 12 октября 2009

Казалось бы, вопрос, который они задавали, был не "Почему нет?" но "Зачем это делать?" Там мало смысла в этом. Там редко нужно копировать в режиме реального времени. Обычно представления шаблонов создаются по протоколу NSCoding (т.е. с помощью Interface Builder), и это почти все, что подходит для копируемого представления.

3 голосов
/ 15 мая 2012

Потому что NSCopying не так хорош в глубоких (рекурсивных) копиях графов объектов. Например, [NSArray copy] копирует список объектов, а не сами объекты. Графы объектов лучше обслуживаются NSCoding. Что в счастливом стечении обстоятельств подтверждается UIView.

Если вы хотите скопировать пользовательский вид со свойствами, вам нужно будет поддерживать NSCoding. Например.,

@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
...