iOS Obj-C 将字节数组转换为 plist 到字符串

iOS Obj-C convert byte array to plist to string

哎呀,我要疯了。

我有以下功能,我正在尝试使用自定义记录器进行记录

CFWriteStreamWrite(CFWriteStreamRef stream, const UInt8 *buffer,
    CFIndex bufferLength) {

NSData *data = [[NSData alloc] initWithBytes:buffer length: bufferLength]; 


NSString *errorDesc = nil;
NSPropertyListFormat format;
NSString * str = (NSString*)[NSPropertyListSerialization
                                      propertyListFromData:data
                                      mutabilityOption:NSPropertyListMutableContainersAndLeaves
                                      format:&format
                                      errorDescription:&errorDesc];


custom_log(CF, "CFURLCreateWithString: %s", str);
}

当我使用我的自定义记录器时,我得到垃圾输出

CFURLCreateWithString: <       °3€

但是当使用 NSLog 时,一切正常,

Feb 10 00:36:39: {
        bundleID = "com.test.testapp";
        pid = 2852;
    }

自定义记录器

EXPORT void custom_log(unsigned int facility, const char *msg, ...) {
if (minLogLevel <= INFO) {
    char *msgBuffer;
    va_list args;
    va_start(args, msg);
    vasprintf(&msgBuffer, msg, args);
    va_end(args);

    dispatch_async(logQueue, ^{
        write(facility, INFO, msgBuffer);
    });
}
}

请告诉我哪里出错了,过去 3 个小时我一直在尝试转换为不同的数据类型。运气不好。

此外,是否可以将 NSLog 的输出转换成字符串,然后我将它传递给我的记录器?

您可能在这里遇到的问题之一是 NSStringc_str 不同,您的 vasprintf 方法可能期望替代 [=16] =].

为了解决这个问题,我很确定你不能直接将 NSPropertyListSerialization 转换为 NSString,尽管我自己没有测试过。您可能正在寻找这样的替代方案:

NSString * str = [NSString stringWithFormat:@"%@", [NSPropertyListSerialization
                                  propertyListFromData:data
                                  mutabilityOption:NSPropertyListMutableContainersAndLeaves
                                  format:&format
                                  errorDescription:&errorDesc]];


custom_log(CF, "CFURLCreateWithString: %s", [str UTF8String]);

当然,既然您已经在合成一个字符串,为什么不在同一个地方全部完成呢?

NSString * str = [NSString stringWithFormat:@"CFURLCreateWithString: %@", [NSPropertyListSerialization
                                  propertyListFromData:data
                                  mutabilityOption:NSPropertyListMutableContainersAndLeaves
                                  format:&format
                                  errorDescription:&errorDesc]];


custom_log(CF, [str UTF8String]);

作为一个有趣的副业,您可以考虑在 main.mm 中做这样的事情。如果您想要的不仅仅是错误信息,请将 stderr 替换为 stdout

#if COPY_NSLOG_TO_CUSTOM
typedef int (*MyStdWriter)(void *, const char *, int);
static MyStdWriter _oldStdWrite;
int __customStderrWrite(void *inFD, const char *buffer, int size) {
  if (minLogLevel <= INFO) {
    // write to your custom stream here.
  }
  return _oldStdWrite(inFD, buffer, size);
}

void __copyNSLogToCustom(void) {
  _oldStdWrite = stderr->_write;
  stderr->_write = __customStderrWrite;
}
#endif

int main(int argc, char *argv[]) {
#if COPY_NSLOG_TO_CUSTOM
  __copyNSLogToCustom();
#endif
// ...
}