4 votes

Comment puis-je créer une sous-classe de NSInputStream ?

J'aimerais créer une sous-classe de NSInputStream. Simplement, j'ai essayé de coder comme ce qui suit,

@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

et, j'ai utilisé la classe comme suit.

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

Ensuite, dans le runtime, j'ai pu rencontrer le message d'erreur suivant.

-[SeekableInputStream initWithURL :]: sélecteur non reconnu envoyé à l'instance 0x10018ff30

Je n'ai pas surchargé initWithURL pour utiliser la méthode du parent à dessein. D'après mes connaissances, une classe dérivée peut utiliser la méthode de la classe parente, n'est-ce pas ?

Une méthode d'extension comme initWithURL ne peut-elle pas être héritée ?

Quelqu'un peut-il m'informer sur la manière de sous-classer NSInputStream ?

2voto

Rodrigo Points 2692

De 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

Comme vous pouvez le constater, il n'y a pas de fonction initWithURL. Ainsi, votre super ne fonctionne pas, car il n'existe pas vraiment. Comme le dit MrTJ, c'est une classe de catégorie. Elle est définie dans :

// 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);

Donc, je pense que si vous l'utilisez dans votre sous-classe, cela peut fonctionner.

#import <Foundation/NSStream.h>

Vous devez importer la catégorie. Rappelez-vous que vous ne pouvez pas sous-classer une catégorie, vous ne faites que l'écraser et vous ne pouvez pas l'appeler (ou si vous le pouvez, je ne sais pas comment).

0voto

MrTJ Points 4547

Si vous vérifiez NSStream.h dans le SDK, initWithURL n'est pas défini dans la classe de base NSInputStream mais dans une catégorie appelée NSInputStreamExtensions . Je ne sais pas grand-chose sur l'appel de méthodes définies dans une catégorie d'une classe de base à partir d'une classe héritée, mais cela peut certainement être la cause du problème de visibilité que vous rencontrez.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X