這不是一個runLoop或ExternalAccessories問題。 這是一個每日OOP問題。
最好的方法是創建一個可以寫入outputStream並等待響應的通信對象。 使用@協議來做到這一點! (事件監聽器驅動程序)
試試這個:
首先你必須輸入/輸出流附加到runLoop:
[[session inputStream] scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[[session inputStream] open];
[[session outputStream] scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[[session outputStream] open];
成爲他們的代表:
[[session outputStream] setDelegate:self];
[[session inputStream] setDelegate:self];
一旦成爲代表,您必須實施此方法:
-(void)stream:handleEvent:{};
這是將數據寫出到流命令:
/* data is a NSData containing data to transmit. */
[[session outputStream] write:(uint8_t *)[data bytes] maxLength:[data length]];
這是一個示例代碼,(一旦你有會話創建的,而我們期待的答案是一個字節):
在Comm.h:
/* Define your protocol */
@protocol CommDelegate <NSObject>
-(void)byteReceived: (char) byte;
@end
@interface Comm <NSObject> {
[...]
id<CommDelegate> delegate;
}
@end
@property (nonatomic, retain) id<CommDelegate> delegate;
在Comm.m:
@implementation Comm
[...]
-(id)init {
[...]
delegate = nil;
[...]
}
-(void)write: (NSData *) data {
[[session outputStream] write:(uint8_t *)[data bytes] maxLength:[data length]];
}
-(void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)_event {
switch (_event)
{
case NSStreamEventHasBytesAvailable:
/* This part will be executed every time your rx buffer contains at least 1 byte */
switch(state) {
uint8_t ch;
/* Read byte per byte */
[stream read:&ch maxLength:1];
/* now ch contains a byte from your MFI device
** and 'read' function decrease the length of the rx buffer by -1 */
/* Now you can notify this to the delegate
*/
if(self.delegate != nil)
[delegate byteReceived: ch];
}
break;
}
}
your_app_controller。H:
@interface MyApp : UIViewController <CommDelegate> {
Comm comm;
}
@end
your_app_controller.m:
@implementation MyApp
-(id)init {
[...]
comm = [[Comm alloc] init];
[comm setDelegate: self]; /* Now your thread is listening your communication. */
}
-(void)write {
byte out = 'X';
[comm write: [NSData dataWithBytes: &out length: 1]];
}
-(void)bytereceived:(char)reply {
if(reply == 'Y') {
[self write];
//[self performSelectorInBackground:@selector(write) withObject:nil]; IT'S BETTER!!!
}
}
@end
希望這有助於!
但在您的示例中,您正在調度'currentRunLoop'上的流,您並未在另一個線程上安排它們。讀取和寫入操作似乎也在主線程上執行。 –
一個「runloop」運行在一個線程的空閒時間,它不會阻塞......在這種情況下,當一個字節變爲可用時,通知被觸發(NSStreamEventHasBytesAvailable)。我可以通過'[stream read:&ch maxLength:1];'來讀取字節。從一個向量讀取一個字節,此操作速度很快。當然,該字節是在主線程中讀取的,但不會阻塞。 –
謝謝你的回答!無論如何,我沒有說明我的評論背後的原因,對不起:P我並不是說你錯了,或者你的解決方案有問題,但只是評論'現在你可以通知代表(你的主線程) '是有點誤導,因爲你已經在主線程:) –