편집 :이 답변은 이제 오래된, 요즘 ORSSerialPort 여기에 설명 정확히 시나리오를 처리 할 수 built in API이 포함되어 있습니다. 이제 같은 작업을 수행 할 수 있습니다
@implementation MyClass
- (void)updateItems
{
// We can just send these all in a for loop. ORSSerialPort will handle
// queuing them and waiting for a response to each before going on to the next request
for (NSData *command in self.commands) {
ORSSerialPacketDescriptor *response =
[[ORSSerialPacketDescriptor alloc] initWithPacketData:[@"foo" dataUsingEncoding:NSASCIIStringEncoding] userInfo:nil];
ORSSerialRequest *request = [ORSSerialRequest requestWithDataToSend:command userInfo:nil timeoutInterval:1.0 responseDescriptor:response];
[self.serialPort sendRequest:request];
}
}
- (void)serialPort:(ORSSerialPort *)serialPort didReceiveResponse:(NSData *)data toRequest:(ORSSerialRequest *)request
{
NSLog(@"Received response: %@ to request: %@", data, request.dataToSend);
if (serialPort.queuedRequests.count == 0) {
// All done! Do whatever comes next.
}
}
- (void)serialPort:(ORSSerialPort *)serialPort requestDidTimeout:(ORSSerialRequest *)request
{
// Something went wrong!
[self.serialPort cancelAllQueuedRequests]; // Stop sending the rest of the commands
}
아래 원래 답 :
내가 뭘하는 명령 큐를 유지하는 것입니다을 확인할 수 있습니다. 가장 최근에 보낸 명령 (또는 응답을 기다리는 시간 초과)에 대한 적절한 회신을받은 후 대기열에서 다음 명령을 보냅니다.
당신이 뭔가를 할 수 있어야한다 :이 코드/방법에 대한
@interface MyClass()
@property BOOL waitingForAck;
@end
@implementation MyClass
- (void)updateItems
{
for (NSData *command in self.commands) {
[self.serialPort sendData:command];
self.waitingForAck = YES;
while (self.waitingForAck) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
beforeDate:[NSDate distantFuture]];
}
}
}
- (void)serialPort:(ORSSerialPort *)serialPort didReceiveData:(NSData *)data
{
NSLog(@"Received Data");
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
if([string isEqualTo:@"0\r\n"]) //ack signal
{
//Serial port is now ready to accept another instruction
self.waitingForAck = NO;
}
}
@end
몇 노트. 오류에 대해서는 현명하지 않습니다. 현재 작성된대로 시간 제한이 없으므로 어떤 이유에서든 Arduino가 명령에 응답하지 않으면 -updateItems
이 영원히 돌아갑니다. 실시간 시간 제한을 추가하여 문제를 해결할 수 있습니다. 기본적으로 명령을 보낸 시간을 기록한 다음 waitingForAck
이 명령을 보낸 시간의 1 초 (또는 그 이상) 내에 YES로 설정되지 않은 경우 -updateItems
에서 벗어나 오류를 적절하게 처리합니다.
이 코드에는 멀티 스레드가 포함되어 있지 않으며 모든 것이 주 스레드에서 수행됩니다 (ORSSerialPort는 내부적으로 백그라운드 스레드를 사용하지만 사용자는 신경 쓸 필요가 없습니다).
실행 루프를 -updateItems
으로 돌리면 코드의 다른 부분이 계속 실행됩니다. updateItems
을 호출하는 코드는 반환되기를 기다리는 것을 차단하지만 UI는 계속 응답합니다.이를 방지하려면 -updateItems
의 시작 부분에 UI의 관련 부분을 사용 중지해야합니다. 예를 들어 진행 표시기 완료된 후에 다시 활성화하십시오.