【问题标题】:How can I clone a NSCoding compliant object into a subclass of it?如何将符合 NSCoding 的对象克隆到它的子类中?
【发布时间】:2016-09-21 22:10:05
【问题描述】:

我有一个NSPopUpButtonCell 的自定义子类,这样我就可以覆盖它的drawBezelWithFrame:inView: 方法。

目前,我必须使用initTextCell:pullsDown: 创建一个新实例,然后手动复制其所有属性。这相当乏味且容易出错,因为我可能会遗漏一些属性。

我想知道我是否可以使用initWithCoder: 代替此任务。我想我应该能够将现有 NSPopUpButtonCell 实例中的数据归档到 NSCoder 对象中,例如进入NSKeyedArchiver,然后将该数据归档回我的NSPopUpButtonCell 子类。但我不知道如何做到这一点。

【问题讨论】:

  • 如何以编程方式或 XIB 创建弹出按钮?
  • @Willeke 从一个笔尖,我已经知道我可以更轻松地解决那个特定的问题。尽管如此,我还是想了解是否有办法克隆它的子类中的任何对象。

标签: macos cocoa nscoder


【解决方案1】:

如果您的子类所做的只是覆盖方法,即它不添加额外的字段,那么您可以调换您原来的 NSPopupButtonCell 的类或它的副本,因此它成为您的子类的实例。

Apple 使用这种技术实现 KVO,在这种情况下使用动态生成的子类。如果您的情况下子类是静态的,则更容易,代码大纲是:

object_setClass(<an NSPopupButtonCell instance>,
                [<your subclass> class]);

如果您可以安全地更改原始实例上的类,那么这根本不需要创建或复制对象。

请记住,您只能仅在子类更改行为时才这样做

其他解释见this answer

HTH

【讨论】:

    【解决方案2】:

    看来我之前只是使用了错误的功能。解决方案非常简单。

    这段代码将 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 子类的另一种更简洁的方法:Using full width of NSPopupButton for text, no arrows

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-04
      • 1970-01-01
      • 1970-01-01
      • 2021-04-29
      • 2011-01-20
      • 2017-05-09
      • 1970-01-01
      • 2013-10-12
      相关资源
      最近更新 更多