【问题标题】:How to share code between 2 classes that have the same root class?如何在具有相同根类的 2 个类之间共享代码?
【发布时间】:2012-07-09 12:53:46
【问题描述】:

我创建了一个名为RCTextField 的自定义类,其目的是创建一个带有圆角的NSTextField(因此是RC...)。

RCTextField 继承自NSTextField 并覆盖drawRect: 方法以创建自己的圆角矩形。

现在,我想对NSSecureTextField 做同样的事情,即有办法让它有圆角。我不能让它继承RCTextField,因为它没有任何secure 实现NSSecureTextField 拥有的文本。

如果我从NSSecureTextField 继承,我将不得不再次重写所有drawRect: 实现。

我想到的一个选项是拥有一个 RCBaseTextField 类,其中包含一个名为 drawRect:forNSTextField:withParams: 的静态方法,并在 RCTextFieldRCSecureTextFielddrawRect: 中调用该方法。然而,这似乎有点骇人听闻,感觉在 Objective-C 中可能有更好的 OOP 方式来做到这一点。

那么,在RCTextFieldRCSecureTextField 之间共享RCTextField 的圆角圆角代码的最佳/最健全/软件工程“esquest”方法是什么?

【问题讨论】:

    标签: objective-c macos cocoa oop inheritance


    【解决方案1】:

    不幸的是,你不能让 Objective-C 继承更多的其他类的行为。我认为提供一个将由drawRect: 实现调用的函数(使用面向对象的语言并不会阻止在适当时使用函数)是更简单的方法。

    或者您可以忽略NSSecureTextField 并让RCSecureTextField 继承自RCTextField。然后实现类方法cellClass返回NSSecureTextFieldCell,你应该得到与NSSecureTextField完全相同的特性。

    @interface RCSecureTextField : RCTextField
    @结尾
    
    @implementation RCSecureTextField
    + (Class)cellClass { return [NSSecureTextFieldCell 类]; }
    @结尾
    
    

    【讨论】:

    • 我想知道如果单独实现 +cellClass,他的 RSSecureTextField 类是否将拥有他需要的所有行为作为 NSSecureTextField(我不知道 NSSecureTextField 的详细信息)。
    • 根据NSSecureTextField 文档:NSSecureTextField 使用NSSecureTextFieldCell 来实现其用户界面。
    • 我尝试以编程方式执行此操作,但它不起作用。如果单元格是 Interface Builder 中的 NSTextFieldCell,即使我在 cellClass 中说它应该返回 [NSSecureTextFieldClass class],它也会继续是 NSTextFieldCell。但是,当我将 Interface Builder 中的单元格类型更改为 NSSecureTextFieldCell 时,这确实有效...
    • 是的,cellClass 仅在使用 initWithFrame: 创建文本视图时使用。在 Interface Builder 中创建文本视图时,其单元格与 XIB/NIB 一起存档。
    • 函数不是面向对象的。使用组合。 en.wikipedia.org/wiki/Design_Patterns
    【解决方案2】:

    我发现对象组合有助于解决这种情况。将所有共享的方法移动到一个单独的类中,然后让 RCTextFieldRCSecureTextField 满足您的帮助类并适当地调用这些方法。

    【讨论】:

      【解决方案3】:

      听起来像是依赖注入的案例(注意:NSSecureTextField 继承自 NSTextField):

      @interface RCTextField : NSObject {
        NSTextField *textField
      }
      - (id) initWithTextField:(NSTextField *)_textField;
      
      @end
      

      然后只公开你想要的任何功能。

      【讨论】:

        【解决方案4】:

        用这个原型制作一个 C 函数:

        void drawTextFieldRoundRect(NSTextField* instance, CGRect rect);
        

        在名为(比如)TextFieldRounded.h 的文件中声明,并在相应的 TextFieldRounded.m 中定义(不包含类,只有这个 C 函数。但将其设为 .m,以便您可以使用 Objective-C 语法)。

        在此函数中,您可以执行自定义绘图。您可以通过参数instance 访问“self”。

        接下来,在RCTextField 中,您可以像这样实现-drawRect:

        #import "TextFieldRounded.h"
        
        - (void) drawRect:(CGRect) rect
        {
            drawTextFieldRoundRect(self, rect);
        }
        

        (对RCSecureTextField做同样的事情)

        不是最优雅的,我知道...

        选项 2:如果您仅使用圆角文本字段,您可以在 NSTextField 上添加一个类别,并且 NSSecureTextField 应该继承“圆角”行为。但是,如果您想要圆角 普通文本字段,那就不行了。

        【讨论】:

        • 这里不需要对 ARC 进行特殊处理。
        • 你是对的; (唯一)接收端仅操作作为函数参数的对象。我删除了那行。
        【解决方案5】:

        您可能想要继承NSTextFieldCell,而不是控件。我会继承NSSecureTextFieldCell 并在两个控件中使用它;从绘图的角度来看,唯一的区别是echosBullets 属性的值。

        【讨论】:

          猜你喜欢
          • 2012-10-21
          • 2018-05-25
          • 2020-07-09
          • 1970-01-01
          • 2019-07-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-11-11
          相关资源
          最近更新 更多