【问题标题】:Cast of a non-Objective-C pointer type 'const UInt8 *' (aka 'const unsigned char *') to 'NSData *' is disallowed with ARCARC 不允许将非 Objective-C 指针类型“const UInt8 *”(又名“const unsigned char *”)转换为“NSData *”
【发布时间】:2014-03-14 04:59:29
【问题描述】:

好的,我对 Obj-C 和 iOS 完全陌生。我只是在 iOS 上试用 Pebble 手表的 DataLogging 示例并更改一些内容以记录加速度计读数。

我有这个功能:

- (BOOL)dataLoggingService:(PBDataLoggingService *)service hasByteArrays:(const UInt8 *const)data numberOfItems:(UInt16)numberOfItems forDataLoggingSession:(PBDataLoggingSessionMetadata *)sessionMetadata{

    //NSString *log = [NSString stringWithFormat:@"%s", data]; <-- this line compiles but display garbage on the view. So I try to use the line below.

    NSString *log = [[NSString alloc] initWithData:(NSData *)data encoding:NSASCIIStringEncoding]; <-- this line gave build error as in the post title

    [self addLogLine:log];

    // We consumed the data, let the data logging service know:
    return YES;
}

因此,我们将不胜感激任何帮助。谢谢。

【问题讨论】:

  • downvote 真的很有帮助。谢谢。

标签: ios objective-c pebble-watch


【解决方案1】:

首先你的错误:它告诉你不能将指针指向不是Objective-C对象的东西——你有一个指向UInt8的指针——只需将它转换为指向Objective-C对象的指针—— NSData 在您的情况下,ARC(Objective-C 内存收集器)不知道如何处理结果。如果可能,您可以使用 bridge cast 来解决这个问题,告诉 ARC 如何处理它。但是,在您的情况下,这是不可能的,因为您不能只将 UInt8 * 转换为 NSData * - 两者指的是完全不同的东西。

猜测您的方法会传递一个指向字节序列 (hasByteArrays:) 的指针和序列中的字节数 (numberOfItems),如果正确,那么您所追求的方法是 initWithBytes:length:encoding: ,这个方法直接接受一个指向字节序列的指针。例如:

NSString *log = [[NSString alloc] initWithBytes:data
                                         length:numberOfItems
                                       encoding:NSASCIIStringEncoding];

【讨论】:

  • 赞成以感谢您的帮助。我仍然在视图上显示垃圾,更改为 UTF8 编码会使应用程序崩溃。如果我这样做:for (int i = 0; i &lt; numberOfItems; ++i) { NSString *log = [NSString stringWithFormat:@"%hhu", data[i]]; [self addLogLine:log]; } 它可以工作并显示加速度计数据。有什么想法吗?
  • 听起来你的字节无符号数值根本不是字符。将随机字节值转换为字符会产生随机混乱。你的目标是什么?如果您想保留 Obj-C 对象中的字节以便以后访问它们,请使用由 dataWithBytes:length: 构造的 NSData 对象。如果您想获得它们的文本表示,那么您的 for 循环就是要走的路。您可以在循环之前将log 创建为NSMutableString,并在循环内调用appendFormat:。然后在循环之后,您将在log 中将字节的文本表示为十六进制字符串。
  • 你说得对,这些字节是来自 AccelData structx,y,z uint16_t,它们是 little_endians,我正在尝试将它们记录到文本文件中。所以可能NSMutableString 是要走的路,但不是string of hex
  • 我的十六进制不好,你使用的是“u”格式。如果日志记录是您的目标,而不是创建一个字符串,请执行您正在执行的操作,但也要定期添加换行符。如果它们是uint16_t,则将您的指针投射到uint16_t * 并按原样读取它们。您可以使用CFSwapInt16LittleToHost 让代码交换字节如果需要
【解决方案2】:

尝试以下方法:

- (BOOL)dataLoggingService:(PBDataLoggingService *)service hasByteArrays:(const UInt8 *const)data numberOfItems:(UInt16)numberOfItems forDataLoggingSession:(PBDataLoggingSessionMetadata *)sessionMetadata{

     NSString *log = [NSString stringWithCString:(const char *)data encoding:NSUTF8StringEncoding];

    [self addLogLine:log];

    // We consumed the data, let the data logging service know:
    return YES;
}

【讨论】:

  • 感谢您的帮助。 UTF8 编码使应用程序崩溃,更改为encoding:NSASCIIStringEncoding 工作但仍然显示垃圾。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-08
  • 2023-03-08
  • 1970-01-01
  • 2012-02-08
相关资源
最近更新 更多