이것은 runLoop 또는 ExternalAccessories 문제가 아닙니다. 이것은 매일 OOP 문제입니다.
가장 좋은 방법은 outputStream에 쓸 수 있고 응답을 기다릴 수있는 Communication 개체를 만드는 것입니다. 이렇게하려면 @protocols를 사용하십시오! (이벤트 리스너 구동 절차)
이 시도 : 모든
먼저 당신이 runLoop 입력/출력 스트림을 첨부해야한다 :
[[session outputStream] setDelegate:self];
[[session inputStream] setDelegate:self];
:
이
[[session inputStream] scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[[session inputStream] open];
[[session outputStream] scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[[session outputStream] open];
자신의 대리인이 되십시오
일단 위임되면이 방법을 구현해야합니다.
(당신이 세션을 만든 후에 우리가 기대하는 대답은 바이트 인 반면,)
/* data is a NSData containing data to transmit. */
[[session outputStream] write:(uint8_t *)[data bytes] maxLength:[data length]];
이 예제 코드는 다음과 같습니다 :
-(void)stream:handleEvent:{};
이는 스트림에 데이터를 쓸 수있는 명령입니다 Comm.h에서
: Comm.m에서
/* Define your protocol */
@protocol CommDelegate <NSObject>
-(void)byteReceived: (char) byte;
@end
@interface Comm <NSObject> {
[...]
id<CommDelegate> delegate;
}
@end
@property (nonatomic, retain) id<CommDelegate> delegate;
:
@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시간 :
@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 나는 당신이 틀렸다고 말하거나 당신의 솔루션에 문제가 있다는 말은 아니지만 간단히 말해서 '이제 당신은 위임자에게 이것을 알릴 수있다. (주 스레드) '당신이 이미 메인 스레드에 있기 때문에 약간 오해의 소지가 있습니다 :) –