1

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を呼び出すクラスに明示的なコンストラクターを追加しようとしましたが、違いはありません(そうではないはずです)。

4

3 に答える 3

2

NSOutputStreamのインスタンスを期待するAPIを使用している場合、ラップされた(デリゲート)インスタンスに転送するために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ダックタイピングを使用してNSOutputStreamをより簡単にサブクラス化する方法に関するブログ投稿を参照してください。または、 https://github.com/jwb/ObjC-DuckTypeでサンプルを確認してください

于 2013-12-03T20:57:50.897 に答える
1

NSOutputStreamクラスのドキュメントに記載されている非常に具体的なサブクラス化要件があります。

ドキュメントには、適切な初期化子を完全に実装する必要があると明示的に記載されていることに注意してください。つまり、説明したように動作を変更するためにサブクラス化することはできません。少なくとも、簡単ではありません。

代わりに、インスタンスがのインスタンスをラップするクラスを作成し、NSOutputStream必要な動作を追加します。

于 2012-07-13T04:08:21.127 に答える
0

追記として、のを使用して書き込まれたデータに関する情報を取得できるようにする必要が- propertyForKey:ありNSStreamます。NSStreamDataWrittenToMemoryStreamKeyプロパティキーを確認してください 。

于 2015-04-14T17:26:59.560 に答える