如何将符合 NSCoding 的对象克隆到它的子类中?
How can I clone a NSCoding compliant object into a subclass of it?
我有一个 NSPopUpButtonCell
的自定义子类,这样我就可以覆盖它的 drawBezelWithFrame:inView:
方法。
目前,我必须使用 initTextCell:pullsDown:
创建一个新实例,然后手动复制其所有属性。这相当乏味且容易出错,因为我可能会遗漏一些属性。
我想知道我是否可以使用 initWithCoder:
代替此任务。我想我应该能够将现有 NSPopUpButtonCell
实例中的数据归档到 NSCoder
对象中,例如到 NSKeyedArchiver
,然后将该数据归档回我的 NSPopUpButtonCell
子类。但我不知道如何实现。
如果您的所有 subclass 所做的只是覆盖方法,即它不添加额外的字段,那么您可以调配原始 NSPopupButtonCell
的 class 或它,所以它变成了你的 subclass.
的实例
Apple 使用此技术实现 KVO,在这种情况下使用动态生成的子class。如果你的情况下 subclass 是静态的,那么就容易多了,代码的大纲是:
object_setClass(<an NSPopupButtonCell instance>,
[<your subclass> class]);
如果您可以安全地更改原始实例上的 class,那么这根本不涉及对象创建或复制。
请记住,您可以仅在子class 仅更改行为 时才执行此操作。
另一种解释见this answer。
HTH
看来我之前用错了功能。隔离非常简单。
此代码将 NSPopUpButtonCell 的属性复制到它的子类中,这样我就可以覆盖它的绘制...方法:
@interface MyPopup : NSPopUpButton
@end
@implementation MyPopup
- (instancetype)initWithCoder:(NSCoder *)coder {
self = [super initWithCoder:coder];
if (self) {
// Set up the archiver
NSMutableData *data = [NSMutableData data];
NSKeyedArchiver *arch = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
// Archive the cell's properties
[self.cell encodeWithCoder:arch];
[arch finishEncoding];
// Set up the unarchiver
NSKeyedUnarchiver *ua = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
// Create a subclass of the cell's class, using the same properties
MyCell *newCell = [[MyCell alloc] initWithCoder:ua];
// Assign the new subclass object as the NSButton's cell.
self.cell = newCell;
}
return self;
}
此处显示了使用自定义 NSButtonCell 子类的另一种更简洁的方法:
我有一个 NSPopUpButtonCell
的自定义子类,这样我就可以覆盖它的 drawBezelWithFrame:inView:
方法。
目前,我必须使用 initTextCell:pullsDown:
创建一个新实例,然后手动复制其所有属性。这相当乏味且容易出错,因为我可能会遗漏一些属性。
我想知道我是否可以使用 initWithCoder:
代替此任务。我想我应该能够将现有 NSPopUpButtonCell
实例中的数据归档到 NSCoder
对象中,例如到 NSKeyedArchiver
,然后将该数据归档回我的 NSPopUpButtonCell
子类。但我不知道如何实现。
如果您的所有 subclass 所做的只是覆盖方法,即它不添加额外的字段,那么您可以调配原始 NSPopupButtonCell
的 class 或它,所以它变成了你的 subclass.
Apple 使用此技术实现 KVO,在这种情况下使用动态生成的子class。如果你的情况下 subclass 是静态的,那么就容易多了,代码的大纲是:
object_setClass(<an NSPopupButtonCell instance>,
[<your subclass> class]);
如果您可以安全地更改原始实例上的 class,那么这根本不涉及对象创建或复制。
请记住,您可以仅在子class 仅更改行为 时才执行此操作。
另一种解释见this answer。
HTH
看来我之前用错了功能。隔离非常简单。
此代码将 NSPopUpButtonCell 的属性复制到它的子类中,这样我就可以覆盖它的绘制...方法:
@interface MyPopup : NSPopUpButton
@end
@implementation MyPopup
- (instancetype)initWithCoder:(NSCoder *)coder {
self = [super initWithCoder:coder];
if (self) {
// Set up the archiver
NSMutableData *data = [NSMutableData data];
NSKeyedArchiver *arch = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
// Archive the cell's properties
[self.cell encodeWithCoder:arch];
[arch finishEncoding];
// Set up the unarchiver
NSKeyedUnarchiver *ua = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
// Create a subclass of the cell's class, using the same properties
MyCell *newCell = [[MyCell alloc] initWithCoder:ua];
// Assign the new subclass object as the NSButton's cell.
self.cell = newCell;
}
return self;
}
此处显示了使用自定义 NSButtonCell 子类的另一种更简洁的方法: