objective-csubclassingnsoutputstream

How to create a subclass of NSOutputStream


I am trying to write a subclass of NSOutputStream to perform a very simple function - keep track of the total number of bytes sent to the stream. However, I am running into an unexpected problem initializing an instance of the function. Here is the code:

#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

However, when I try to initialize this class:

TrackingOutputStream *os = [[[TrackingOutputStream alloc] initToFileAtPath:@"/tmp/test" append:NO] autorelease];

I get the following error:

-[TrackingOutputStream initToFileAtPath:append:]: unrecognized selector sent to instance 0x101a187e0

I've tried adding an explicit constructor to the class that calls super, but it doesn't make any difference (as it shouldn't).


Solution

  • NSOutputStream has very specific subclassing requirements that are documented in the class's documentation.

    Note that the documentation explicitly states that you must implement the appropriate initializers fully. I.e. you can't subclass to change the behavior as you described. At least, not easily.

    Instead, create a class whose instances wrap an instance of NSOutputStream and add the behavior you desire.