2012-04-04 23 views
4

NSInputStreamのサブクラスを作りたいと思います。単純に、次のようにコードを作成しようとしました。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は:]:認識されていないセレクタは、私は意図的に親のメソッドを使用するためのinitWithURLを上書きしませんでしたインスタンスに0x10018ff30

を送りました。 私の知識に基づいて、派生クラスは親クラスのメソッドを使用できますか?

initWithURLのような拡張メソッドを継承することはできませんか?

誰かがNSInputStreamのサブクラス化を行う方法を知らせていますか?

+0

メソッド 'initWithURL'を実際に再実装しようとしましたか(試してみたことがありますか?)あなたはどのようなカテゴリをサブクラス化できないのでしょうか? – Saphrosit

+0

@Saphrositあなたは「オーバーライド」として「再実装」を意味しますか?はいの場合は、はいと言うことができます。私はinitWithURLメソッドをオーバーライドしましたが、スーパーインスタンスにはメソッドがないため、[super initWithURL]呼び出しは失敗しました。 –

+0

NSInputStreamは何とか "特別な"ものかもしれませんが、どこかで何か汚れてしまったことを強く疑うでしょう。たとえば、MファイルにHファイルのそのバージョンを実際に含めていません。 –

答えて

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> 

カテゴリをインポートする必要があります。

+1

CFStreamCreateBoundPairは、NSInputStreamをサブクラス化してプライベートAPI [1]をオーバーライドしようとするよりも安全であると考えられています。しかし、AFNetworkingには問題がありました。残念ながらプライベートAPIのオーバーライドは今のところ最高の解決策です[2]。 [1]:http://osdir.com/ml/general/2012-02/msg08594.html [2]:https://github.com/AFNetworking/AFNetworking/pull/1044 –

+0

@HeathBorders CFStreamCreateBoundPair他の問題の解決に役立つかもしれませんが、OPの問題に役立つかどうかは不明です。 AFNetworkingがサブクラスを実装している方法であるIMHOは間違っているだけでなく、特に問題なく動作するプライベートAPIを使用しないため、非常に薄い氷上を歩いています時間。 – CouchDeveloper

+0

スレッドを読んだら、私はリンクして、試してバグに遭遇しました。私は彼らがパブリックAPIに固執すべきだと思うが、最終的には動作するコードが勝つことに同意する。 –

0

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

関連する問題