创建和使用虚拟NSData子类不起作用

F'x*_*F'x 3 cocoa objective-c nsdata

我有一个创建自己的子类的问题NSData,我希望有一个自定义description方法.甚至创建一个虚拟NSData子类:

@interface MyData : NSData {}
@end
Run Code Online (Sandbox Code Playgroud)

@implementation MyData
@end
Run Code Online (Sandbox Code Playgroud)

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

  • 什么是指定的初始化器NSData
  • 我需要为虚拟子类写的最小值是NSData多少?

Jos*_*ell 10

创建NSData子类很困难,因为(正如drewag所说)它是类集群的成员.从二进制数据编程指南:

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

当你这样做时,[[NSData alloc] initWith...]你不会回来NSData; 你可能会回来的NSConcreteData.非凡的Cocoa With Love有一个子类化类集群的讨论和演示.

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

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

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

这将是迄今为止最好创建一个前缀的类和方法:

@interface NSData (FX_Description) 
- (NSString *)FX_description;
@end
Run Code Online (Sandbox Code Playgroud)

Apple文档特别提到了这种类别覆盖技术,并提出反对意见:

因为在类别中声明的方法被添加到现有类中,所以您需要非常小心方法名称.

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

早期版本的文档继续说:

某些类别方法的存在可能会导致所有框架的行为更改.例如,如果你重写windowWillClose:委托方法在类别上NSObject,在你的程序响应,那么所有窗口代表使用类中的方法; 您所有实例的行为NSWindow可能会发生变化.您在框架类上添加的类别可能会导致行为发生神秘变化并导致崩溃.[强调我的.]