【问题标题】:Creating and using a dummy NSData subclass doesn't work创建和使用虚拟 NSData 子类不起作用
【发布时间】:2011-04-24 18:11:19
【问题描述】:

我在创建自己的NSData 子类时遇到问题,我想要一个自定义的description 方法。甚至创建一个虚拟的NSData 子类:

@interface MyData : NSData {}
@end

@implementation MyData
@end

并且使用它会导致奇怪的错误(使用它的函数永远不会退出,并且控制会以某种方式返回到运行循环)。我想也许我负责重写NSData 的指定初始化程序(调用super 实现),但文档中没有提到。所以:

  • NSData 的指定初始化器是什么?
  • 对于NSData 的虚拟子类,我需要编写的最低限度是多少?

【问题讨论】:

    标签: objective-c cocoa nsdata


    【解决方案1】:

    创建NSData 子类很困难,因为(如drewag noted)它是class cluster 的成员。来自Binary Data Programming Guide

    ...数据对象不是 NSData 或 NSMutableData 类的实际实例,而是它们的私有子类之一的实例。

    当您执行[[NSData alloc] initWith...] 时,您不会得到NSData;您可能会收到NSConcreteData。非凡的 Cocoa With Love 有一个 discussion and demonstration 的子类集群。

    最好的(也是最惯用的)选项可能是composition:您的自定义类应该只包含一个NSData ivar,并实现一个对该封闭对象进行操作的描述方法。

    虽然 drawag 的响应在技术上是正确的,但在 Cocoa 类上使用这是一种危险的技术;它将覆盖程序中每个 NSData 对象的description 方法,无论您是否直接创建它。

    description 方法的特定情况下,这可能没问题,但对于框架中其他对象更可能依赖的另一种方法,它可能会导致大的、难以追踪的问题。只有当您确定没有其他方法时,您才应该这样做。

    创建一个带有前缀的类别和方法会更好:

    @interface NSData (FX_Description) 
    - (NSString *)FX_description;
    @end
    

    Apple 文档 specifically mention 这种类别覆盖技术并建议不要使用它:

    由于类别中声明的方法被添加到现有类中,因此您需要非常小心方法名称。

    如果一个类别中声明的方法的名称与原始类中的方法名称相同,或者同一类(甚至超类)上的另一个类别中的方法名称相同,则行为未定义至哪个方法实现在运行时使用。

    文档的早期版本接着说:

    某些类别方法的存在可能会导致所有框架的行为发生变化。例如,如果您在NSObject 的类别中覆盖windowWillClose: 委托方法,则程序中的所有窗口委托都将使用该类别方法响应;您所有NSWindow 实例的行为可能会发生变化。您在框架类上添加的类别可能会导致行为的神秘变化并导致崩溃。 [强调我的。]

    【讨论】:

      【解决方案2】:

      如果您只想覆盖单个函数“描述”,请考虑改用“类别”:

      @interface NSData (MyData)
      -(NSString*)description;
      @end
      
      @implimentation NSData (MyData)
      -(NSString*)description
      {
          return @"something";
      }
      @end
      

      然后,您可以在任何 NSData 实例上使用此函数。

      子类化 NSData 非常困难,因为它是一个“类簇”。公共 API 将其视为一个类,但实际上它是隐藏子类的集合。您可以研究覆盖类集群,但几乎从不需要它。另一种选择是使用 NSData 作为成员变量来创建“MyData”类,而不是使用子类。

      【讨论】:

        猜你喜欢
        • 2013-04-01
        • 2021-04-25
        • 2022-01-12
        • 1970-01-01
        • 2012-07-11
        • 1970-01-01
        • 2020-06-18
        • 1970-01-01
        • 2015-12-09
        相关资源
        最近更新 更多