objective-c - 如何创建 NSInputStream 的子类?

标签 objective-c cocoa

我想创建一个 NSInputStream 的子类。简单地说,我尝试像下面这样编写代码,

@interface SeekableInputStream : NSInputStream
{
    NSUInteger startOffset;
    NSUInteger totalReadLen;
}

- (NSInteger)read:(uint8_t *)buffer maxLength:(NSUInteger)len;
- (BOOL)getBuffer:(uint8_t **)buffer length:(NSUInteger *)len;
- (BOOL)hasBytesAvailable;
- (void)open:(NSUInteger)offset;

@end

并且,我使用了如下类。

SeekableInputStream *stm = [[SeekableInputStream alloc] initWithURL:url];

然后,在运行时,我会遇到以下错误消息。

-[SeekableInputStream initWithURL:]: 无法识别的选择器发送到实例 0x10018ff30

我并没有因为故意使用父方法而覆盖 initWithURL。 据我所知,派生类可以使用父类的方法,不是吗?

不能继承initWithURL这样的扩展方法吗?

有没有人告诉我如何对 NSInputStream 进行子类化?

最佳答案

来自 NSStream.h

// NSStream is an abstract class encapsulating the common API to NSInputStream and NSOutputStream.
// Subclassers of NSInputStream and NSOutputStream must also implement these methods.
@interface NSStream : NSObject
- (void)open;
- (void)close;

- (id <NSStreamDelegate>)delegate;
- (void)setDelegate:(id <NSStreamDelegate>)delegate;
 // By default, a stream is its own delegate, and subclassers of NSInputStream and NSOutputStream must maintain this contract. [someStream setDelegate:nil] must restore this behavior. As usual, delegates are not retained.

- (id)propertyForKey:(NSString *)key;
- (BOOL)setProperty:(id)property forKey:(NSString *)key;

- (void)scheduleInRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode;
- (void)removeFromRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode;

- (NSStreamStatus)streamStatus;
- (NSError *)streamError;
@end

// NSInputStream is an abstract class representing the base functionality of a read stream.
// Subclassers are required to implement these methods.
@interface NSInputStream : NSStream
- (NSInteger)read:(uint8_t *)buffer maxLength:(NSUInteger)len;
// reads up to length bytes into the supplied buffer, which must be at least of size len. Returns the actual number of bytes read.

- (BOOL)getBuffer:(uint8_t **)buffer length:(NSUInteger *)len;
// returns in O(1) a pointer to the buffer in 'buffer' and by reference in 'len' how many bytes are available. This buffer is only valid until the next stream operation. Subclassers may return NO for this if it is not appropriate for the stream type. This may return NO if the buffer is not available.

- (BOOL)hasBytesAvailable;
// returns YES if the stream has bytes available or if it impossible to tell without actually doing the read.
@end

如您所见,没有 initWithURL 函数。所以,你的 super 不起作用,因为它真的不存在。正如 MrTJ 所说,它是一个类别类。它定义于:

// The NSInputStreamExtensions category contains additional initializers and convenience routines for dealing with NSInputStreams.
@interface NSInputStream (NSInputStreamExtensions)
- (id)initWithURL:(NSURL *)url NS_AVAILABLE(10_6, 4_0);

所以,我认为如果你在你的子类中使用它,它就可以工作。

#import <Foundation/NSStream.h>

您需要导入类别。记住你不能子类化一个类别,只是覆盖它然后不能调用(或者如果可以,我不知道如何)

关于objective-c - 如何创建 NSInputStream 的子类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10009867/

相关文章:

iphone - 从后台线程访问 NSManagedObject

objective-c - 如何在iOS中的UItableview中处理100000行

objective-c - 如何使用 [[NSAppleScript alloc] initWithSource : 检查应用程序是否正在运行

macos - Mac OS X/iOS : How to write indexed PNG image using RGBA colours through CGImage?

objective-c - NSNotifications 的最佳实践

ios - 使用 afnetworking 一次下载一个文件

cocoa - 在cocoa编程中如何让一个函数每帧都被调用?

swift - 在 ViewController 中处理菜单项操作

c++ - 如何正确地将回调从 C++ 引擎返回到 obj-c 程序?

swift - 绑定(bind)值更改时 NSButton 标题不更新