我正在尝试编写NSOutputStream的一个子类来执行一个非常简单的功能-跟踪发送到流的总字节数。然而,我在初始化函数的实例时遇到了一个意外的问题。代码如下:
#import <Foundation/Foundation.h>
@interface TrackingOutputStream : NSOutputStream {
unsigned long long bytesWritten;
}
@property (readonly) unsigned long long bytesWritten;
@end
---------------------------
#import "TrackingOutputStream.h"
@implementation TrackingOutputStream
@synthesize bytesWritten;
- (NSInteger)write:(const uint8_t *)buffer maxLength:(NSUInteger)length {
NSInteger written = [super write:buffer maxLength:length];
bytesWritten += written;
return written;
}
@end但是,当我尝试初始化这个类时:
TrackingOutputStream *os = [[[TrackingOutputStream alloc] initToFileAtPath:@"/tmp/test" append:NO] autorelease];我得到以下错误:
-[TrackingOutputStream initToFileAtPath:append:]: unrecognized selector sent to instance 0x101a187e0我尝试向调用super的类添加一个显式构造函数,但这没有任何区别(因为它不应该如此)。
发布于 2012-07-13 12:08:21
class's documentation中记录了NSOutputStream有非常具体的子类化要求。
请注意,文档中明确指出,您必须完全实现适当的初始化器。也就是说,你不能通过子类来改变你所描述的行为。至少,不是那么容易。
相反,可以创建一个类,该类的实例包装了NSOutputStream的一个实例,并添加了所需的行为。
发布于 2013-12-04 04:57:51
如果您正在使用一个需要NSOutputStream实例的应用编程接口,那么实现NSOutputStream的所有方法以便将它们转发到包装的(委托)实例可能会很麻烦。您可以使用方法转发方法,该方法允许您在不编写所有包装方法的情况下添加行为。这涉及到编写一个简单的forwardingTargetForSelector:和respondsToSelector:实现
- (id)forwardingTargetForSelector:(SEL)aSelector {
if (class_respondsToSelector([self class], aSelector)) { return self; }
if ([self.delegate respondsToSelector:aSelector]) { return self.delegate; }
return [super forwardingTargetForSelector:aSelector];
}
- (BOOL)respondsToSelector:(SEL)aSelector {
if (class_respondsToSelector([self class], aSelector)) { return YES; }
if ([self.delegate respondsToSelector:aSelector]) { return YES; }
return [super respondsToSelector:aSelector];
}有关更长、更详细的描述,请参阅使用Objective-C duck-typing to more easily subclass NSOutputStream的博客文章。或者在https://github.com/jwb/ObjC-DuckType上查看示例
发布于 2015-04-15 01:27:00
作为补充说明,应该可以使用NSStream的- propertyForKey:检索有关写入数据的信息。查看NSStreamDataWrittenToMemoryStreamKey属性键。
https://stackoverflow.com/questions/11463828
复制相似问题