ストリームからデータを取得するには、ポーリングとストリーム イベントの使用の 2 つの方法があります。
ポーリングはより単純ですが、実行中のスレッドをブロックします。このメソッドを使用する場合、setDelegate:
またはscheduleInRunLoop:forMode:
呼び出しを実行する必要はありません。を繰り返し呼び出すことでポーリングを行いread:maxLength:
ます。
NSInteger result;
uint8_t buffer[BUFFER_LEN]; // BUFFER_LEN can be any positive integer
while((result = [iStream read:buffer maxLength:BUFFER_LEN]) != 0) {
if(result > 0) {
// buffer contains result bytes of data to be handled
} else {
// The stream had an error. You can get an NSError object using [iStream streamError]
}
}
// Either the stream ran out of data or there was an error
ストリーム イベントを使用するには、デリゲートを設定し、ストリームを実行ループに追加する必要があります。ストリームは、スレッドをブロックする代わりに、stream:handleEvent:
データの受信時など、特定のイベントが発生したときにデリゲートにメッセージを送信します。その後、デリゲートはストリームからデータを取得できます。stream:handleEvent:
メソッドの例を次に示します。
- (void)stream:(NSInputStream *)iStream handleEvent:(NSStreamEvent)event {
BOOL shouldClose = NO;
switch(event) {
case NSStreamEventEndEncountered:
shouldClose = YES;
// If all data hasn't been read, fall through to the "has bytes" event
if(![iStream hasBytesAvailable]) break;
case NSStreamEventHasBytesAvailable: ; // We need a semicolon here before we can declare local variables
uint8_t *buffer;
NSUInteger length;
BOOL freeBuffer = NO;
// The stream has data. Try to get its internal buffer instead of creating one
if(![iStream getBuffer:&buffer length:&length]) {
// The stream couldn't provide its internal buffer. We have to make one ourselves
buffer = malloc(BUFFER_LEN * sizeof(uint8_t));
freeBuffer = YES;
NSInteger result = [iStream read:buffer maxLength:BUFFER_LEN];
if(result < 0) {
// error copying to buffer
break;
}
length = result;
}
// length bytes of data in buffer
if(freeBuffer) free(buffer);
break;
case NSStreamEventErrorOccurred:
// some other error
shouldClose = YES;
break;
}
if(shouldClose) [iStream close];
}