为什么这个条件会导致错误?
Why does this conditional cause an error?
我有一个包含一些条件的方法。第一个条件工作正常,不会引起任何问题。但是,第二个导致应用程序崩溃。
- (void)didReceiveGaiaGattResponse:(CSRGaiaGattCommand *)command
{
GaiaCommandType cmdType = [command getCommandId];
NSData *requestPayload = [command getPayload];
uint8_t success = 0;
NSLog(@"cmdType: %li", (long)cmdType);
[requestPayload getBytes:&success range:NSMakeRange(0, sizeof(uint8_t))];
if (cmdType == GaiaCommand_GetCurrentBatteryLevel && requestPayload.length > 1)
{
uint16_t value = 0;
[requestPayload getBytes:&value range:NSMakeRange(1, sizeof(uint16_t))];
NSInteger battery = CFSwapInt16BigToHost(value);
[self sendEventWithName:someDEVICE_BATTERY_CHANGED body:@{@"batteryLevel":[NSNumber numberWithInteger:battery]}];
return;
}
else if (cmdType == GaiaCommand_GET_FBC && requestPayload.length > 1)
{
uint16_t value = 0;
[requestPayload getBytes:&value range:NSMakeRange(1, sizeof(uint16_t))];
NSInteger feedbackCancellationMode = CFSwapInt16BigToHost(value);
[self sendEventWithName:FEEDBACK_CANCELLATION_MODE body:@{@"feedbackCancellationMode": [NSNumber numberWithInt:feedbackCancellationMode]}];
return;
}
//do more stuff
}
有条件的
if (cmdType == GaiaCommand_GetCurrentBatteryLevel &&
requestPayload.length > 1)
工作没有问题。
但是,条件
else if (cmdType == GaiaCommand_GET_FBC && requestPayload.length > 1)
在 xcode
中引起以下警告
Implicit conversion loses integer precision: 'NSInteger' (aka 'long')
to 'int'
另外,我在调试器中也看到了报错信息
* Terminating app due to uncaught exception 'NSRangeException', reason: '* -[_NSInlineData getBytes:range:]: range {1, 2} exceeds
data length 2'
[NSNumber numberWithInt:feedbackCancellationMode]}]
应该是
[NSNumber numberWithInteger: feedbackCancellationMode]}]
想想这告诉你什么:
Terminating app due to uncaught exception 'NSRangeException', reason:
'-[_NSInlineData getBytes:range:]: range {1, 2} exceeds data length 2'
您的数据对象的长度为 2 个字节。位置 0 的第一个字节是(根据您的代码) success
值。这会在位置 1 处留下一个字节来处理。但是您的代码试图从中复制 2 个字节 — 即消息中的 range {1, 2}
;从位置 1 开始,长度为 2 的范围。您正在阅读数据末尾。
您必须检查数据是否有足够的数据来满足您尝试进行的 -getBytes:...
调用。您可能还需要更正您对缓冲区中取消模式值应该有多大的假设,因为它显然比您预期的要小。您的代码假定它是 uint16_t
(2 个字节),但数据中只剩下一个字节。
我有一个包含一些条件的方法。第一个条件工作正常,不会引起任何问题。但是,第二个导致应用程序崩溃。
- (void)didReceiveGaiaGattResponse:(CSRGaiaGattCommand *)command
{
GaiaCommandType cmdType = [command getCommandId];
NSData *requestPayload = [command getPayload];
uint8_t success = 0;
NSLog(@"cmdType: %li", (long)cmdType);
[requestPayload getBytes:&success range:NSMakeRange(0, sizeof(uint8_t))];
if (cmdType == GaiaCommand_GetCurrentBatteryLevel && requestPayload.length > 1)
{
uint16_t value = 0;
[requestPayload getBytes:&value range:NSMakeRange(1, sizeof(uint16_t))];
NSInteger battery = CFSwapInt16BigToHost(value);
[self sendEventWithName:someDEVICE_BATTERY_CHANGED body:@{@"batteryLevel":[NSNumber numberWithInteger:battery]}];
return;
}
else if (cmdType == GaiaCommand_GET_FBC && requestPayload.length > 1)
{
uint16_t value = 0;
[requestPayload getBytes:&value range:NSMakeRange(1, sizeof(uint16_t))];
NSInteger feedbackCancellationMode = CFSwapInt16BigToHost(value);
[self sendEventWithName:FEEDBACK_CANCELLATION_MODE body:@{@"feedbackCancellationMode": [NSNumber numberWithInt:feedbackCancellationMode]}];
return;
}
//do more stuff
}
有条件的
if (cmdType == GaiaCommand_GetCurrentBatteryLevel && requestPayload.length > 1)
工作没有问题。
但是,条件
else if (cmdType == GaiaCommand_GET_FBC && requestPayload.length > 1)
在 xcode
中引起以下警告Implicit conversion loses integer precision: 'NSInteger' (aka 'long') to 'int'
另外,我在调试器中也看到了报错信息
* Terminating app due to uncaught exception 'NSRangeException', reason: '* -[_NSInlineData getBytes:range:]: range {1, 2} exceeds
data length 2'
[NSNumber numberWithInt:feedbackCancellationMode]}]
应该是
[NSNumber numberWithInteger: feedbackCancellationMode]}]
想想这告诉你什么:
Terminating app due to uncaught exception 'NSRangeException', reason:
'-[_NSInlineData getBytes:range:]: range {1, 2} exceeds data length 2'
您的数据对象的长度为 2 个字节。位置 0 的第一个字节是(根据您的代码) success
值。这会在位置 1 处留下一个字节来处理。但是您的代码试图从中复制 2 个字节 — 即消息中的 range {1, 2}
;从位置 1 开始,长度为 2 的范围。您正在阅读数据末尾。
您必须检查数据是否有足够的数据来满足您尝试进行的 -getBytes:...
调用。您可能还需要更正您对缓冲区中取消模式值应该有多大的假设,因为它显然比您预期的要小。您的代码假定它是 uint16_t
(2 个字节),但数据中只剩下一个字节。