1

我正在使用一个接受CFData对象的 API,我需要动态生成数据,这是一个耗时的操作。消费者以随机、非连续的CFData方式读取它,它实际上很少需要数据的整个长度——它只需要其中的某些随机片段。

我想通过仅实际生成消费者请求的位来提高性能,因为它们是请求的。

有什么方法可以子类化CFData/NSData这样我会在读取数据块时得到回调并即时生成它们?

更新:不幸的是,消费者是第 3 方代码,因此其他类不是一个选项,除非它们以某种方式神奇地与CFData.

4

3 回答 3

0

也许您想要更多类似的东西NSInputStream

NSInputStream 是 NSStream 的子类,提供只读流功能。

NSInputStream 与其 Core Foundation 对应的 CFReadStreamRef 是“免费桥接”的。有关免费桥接的更多信息,请参阅免费桥接。

子类化注释

NSInputStream 是类簇的抽象超类,由 NSStream 的具体子类组成,提供对流数据的标准只读访问。尽管 NSInputStream 对于大多数需要访问流数据的情况可能已经足够了,但是如果您想要更专业的行为(例如,您想要记录流中数据的统计信息),您可以创建 NSInputStream 的子类。

于 2016-06-04T23:15:30.663 回答
0

我不认为你会喜欢你在这里得到的答案。你似乎在选择方面走投无路。

我们对您的情况的了解

  1. 客户的代码不能接受不同的类型/类
  2. CFData是 CoreFoundation C 类型,没有运行时可供使用
  3. 客户端可能使用 CoreFoundation 符号来读取此数据
    1. 如果幸运的话,它是通过 Obj-C 中的 Foundation APIs 实现的,它有一个运行时
  4. CFData包装void *数据,但在开始时有一些填充(可能是结构),如果您尝试创建CFData代理对象,则很难模仿

如果没有一些聪明的、不可维护的和整体危险的符号黑客,我什至都不会费心去研究,要完成你想要的事情将是非常困难的。

于 2016-09-21T19:00:40.257 回答
0

CFDataRef并且NSData是免费桥接的。这意味着,您可以将NSData实例传递到代码中,即期望CFData.

NSData是一个类簇。这意味着,您可以对其进行子类化,并仅实现原始方法和初始化程序。对于NSData原始方法是:

@property (readonly) NSUInteger length;
@property (readonly) const void *bytes NS_RETURNS_INNER_POINTER;

您还必须实现一些init... 方法,该方法将初始化您的实例。

所有其他NSData功能均按类别提供。您仍然可以覆盖任何方法并提供您自己的实现。

作为一种选择,您可以从NSData将任何方法委托给内部NSData实例的子类开始,您可以将其存储在属性中。通过这种方式,您可以观察 3rd 方代码行为并调查您需要覆盖哪些方法。

不过,你需要很多运气才能实现你想要的。但这可能是可能的。

例如,我创建了以下虚拟NSData子类:

@interface MyData : NSData
@property (nonatomic, strong) NSData *innerData;
@end

@implementation MyData

- (id)initWithData:(NSData *)data {
    if (self = [super init]) {
        _innerData = data;
    }
    return self;
}

- (NSUInteger)length {
    NSLog(@"%@", NSStringFromSelector(_cmd));
    return self.innerData.length;
}

- (const void *)bytes {
    NSLog(@"%@", NSStringFromSelector(_cmd));
    return self.innerData.bytes;
}

@end

当我调用以下代码时:

NSData *originalData = [NSData dataWithBytes:"hello" length:5];
MyData *myData = [[MyData alloc] initWithData:originalData];
NSLog(@"%ld", CFDataGetLength((CFDataRef)myData));

length我的子类的方法被调用。

于 2016-09-21T19:35:09.590 回答