4

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 のサブクラス化の方法を教えてくれる人はいますか?

4

2 に答える 2

2

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>

カテゴリをインポートする必要があります。カテゴリをサブクラス化することはできず、上書きして呼び出すことはできません(または、可能であれば、方法がわかりません)。

于 2012-04-04T13:12:11.103 に答える
0

SDK で NSStream.h を確認すると、initWithURLはコア クラスではNSInputStreamなく、 というカテゴリで定義されていますNSInputStreamExtensions。継承されたクラスから基本クラスのカテゴリで定義されたメソッドを呼び出すことについてはあまり知りませんが、これは間違いなく、発生する可視性の問題の原因になる可能性があります。

于 2012-04-04T13:03:20.717 に答える