我正在创建一个NSOutputStream
并将其传递给一个NSOperation
,我从一个调用它NSOperationQueue
。在操作中,我正在轮询hasSpaceAvailable
以便我可以写出到套接字。这在我第一次写入套接字时工作正常。然而,在操作返回后,我尝试再次写入套接字,写入永远不会完成,因为我无限地等待输出套接字中的空间可用。每次写入时我都尝试打开/关闭输出流,但遇到了同样的问题。
我在 init 函数中打开输出流(NSOutputStream
从蓝牙创建EASession
:
_commandSession = [[EASession alloc] initWithAccessory:self.selectedAccessory forProtocol:commandProtocolString];
_commandOutputStream = [_commandSession outputStream];
[_commandOutputStream open];
我还在 init 中创建了操作队列:
_senderOperationQueue = [[NSOperationQueue alloc] init];
_senderOperationQueue.name = @"Send Queue";
_senderOperationQueue.maxConcurrentOperationCount = 1;
我有一个文本字段,其中包含要通过输出流发送的数据。每次单击发送按钮时都会调用此函数:
-(void)sendCommandData:(NSData *)buf
{
_commandSendOperation =[[SenderOperation alloc] initWithStream:_commandOutputStream data:buf delegate:self];
[_senderOperationQueue addOperation:_commandSendOperation];
}
这是我的操作代码的样子:(SenderOperation.h
)
#import <Foundation/Foundation.h>
@protocol SenderOperationDelegate;
@interface SenderOperation : NSOperation
{
NSOutputStream *_stream;
NSData *_sendData;
}
@property (nonatomic, assign) id <SenderOperationDelegate> delegate;
@property (nonatomic, retain) NSOutputStream *stream;
@property (nonatomic, retain) NSData *sendData;
- (id)initWithStream:(NSOutputStream *)stream data:(NSData *)buf delegate:(id<SenderOperationDelegate>)theDelegate;
@end
// Delegate to notify main thread the completion of a BT input buffer stream
@protocol SenderOperationDelegate <NSObject>
-(void)sendComplete:(SenderOperation *)sender;
@end
( SenderOperation.m
)
#import "SenderOperation.h"
@implementation SenderOperation
@synthesize delegate = _delegate;
@synthesize stream = _stream;
@synthesize sendData = _sendData;
- (id)initWithStream:(NSOutputStream *)stream data:(NSData *)buf delegate:(id<SenderOperationDelegate>)theDelegate
{
if (self = [super init])
{
self.delegate = theDelegate;
self.stream = stream;
self.sendData = buf;
}
return self;
}
#define MAX_PACKET_SIZE 20
- (void)main
{
if (self.isCancelled)
return;
// total length of the data packet we need to send
int totalLength = [_sendData length];
// length of packet to send (given our upper bound)
int len = (totalLength <= MAX_PACKET_SIZE) ? totalLength:MAX_PACKET_SIZE;
// stream write response
int streamWriteResponse;
// bytes already written out to the output stream
int bytesWritten = 0;
while (1)
{
if (!len) break;
if ([self.stream hasSpaceAvailable])
{
streamWriteResponse = [self.stream write:[self.sendData bytes] maxLength:len];
if (streamWriteResponse == -1)
{
break;
}
bytesWritten += streamWriteResponse;
// update the data buffer with left over data that needs to be written
if (totalLength - bytesWritten)
self.sendData = [self.sendData subdataWithRange:NSMakeRange(bytesWritten, totalLength - bytesWritten)];
// update length of next data packet write
len = (totalLength - bytesWritten) >= MAX_PACKET_SIZE ? MAX_PACKET_SIZE : (totalLength - bytesWritten);
}
}
[(NSObject *)self.delegate performSelectorOnMainThread:@selector(sendComplete:) withObject:self waitUntilDone:NO];
}