xfd*_*dai 70

治标不治本,只是重新定义都NSLOGprintf在全球头文件.

#define NSLog(FORMAT, ...) printf("%s\n", [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);
Run Code Online (Sandbox Code Playgroud)

  • 我的 NSLog 输出截断了我的序列化 JSON NSData。很烦人。这对我也有用。如果粘贴到 .m 文件的顶部,我只是建议在末尾去掉分号。 (2认同)

Eli*_*ist 42

在iOS 10和Xcode 8中,Apple从旧的ASL(Apple System Log)切换到一个名为的新的日志记录系统Unified logging.NSLog调用实际上是委托给新​​的os_logAPI.(来源:https://developer.apple.com/reference/os/logging):

重要

统一日志记录可在iOS 10.0及更高版本,macOS 10.12及更高版本,tvOS 10.0及更高版本以及watchOS 3.0及更高版本中使用,并取代ASL(Apple System Logger)和Syslog API.历史上,日志消息被写入磁盘上的特定位置,例如/etc/system.log.统一日志记录系统将消息存储在内存和数据存储中,而不是写入基于文本的日志文件.

重要

记录系统存储时,会截断大于系统最大消息长度的日志消息行.使用日志命令行工具查看实时活动流时,可以看到完整消息.但请记住,流式日志数据是一项昂贵的活动.

SDK的标题中显示"系统的最大消息长度"限制为格式化变量的1024个字符,如@Hot_Leaks所述(来源:) <os/log.h>:

/*!  
 * @function os_log  
 *   
 * ...  
 *  
 * There is a physical cap of 1024 bytes per log line for dynamic content,  
 * such as %s and %@, that can be written to the persistence store.  
 * All content exceeding the limit will be truncated before it is  
 * written to disk.  
 *
 * ... 
 *
 */  
#define os_log(log, format, ...)    os_log_with_type(log, OS_LOG_TYPE_DEFAULT, format, ##__VA_ARGS__)
Run Code Online (Sandbox Code Playgroud)

由于缓冲区大小限制似乎是硬编码的libsystem_trace.dylib,我没有看到它的方法,但打印字符串文字而不是格式化的变量(%@),或将格式化的字符串变量拆分为<1024字符串.

printf因为调试器(Xcode)显示进程的输出/错误流,所以它将在调试期间工作,但不会将其发送到设备日志本身.这意味着xfdai的解决方案在使用其他日志应用程序(如macOS的Console应用程序)时,或者在非调试应用程序(例如在客户设备上运行的AppStore应用程序)上出现问题时,将无法帮助您.


扩展xfdai对已部署应用程序的回答

在已部署的应用程序/非调试版本中,无法查看NSLogs或printfs.

将消息直接打印到设备日志(可以使用Xcode - > Window - > Devices,mac的Console App或第三方实用程序(如deviceconsole)访问)的唯一方法是调用os_logAPI(这是ASL自iOS 10以来使用的继承者)).

这是我用来重新定义NSLog_os_log_internaliOS 10上的调用的全局头文件:

#ifndef PrefixHeader_pch
#define PrefixHeader_pch

#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#endif

#import <os/object.h>
#import <os/activity.h>

/*
 *  System Versioning Preprocessor Macros
 */

#define SYSTEM_VERSION_EQUAL_TO(v)                  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)
#define SYSTEM_VERSION_GREATER_THAN(v)              ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN(v)                 ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v)     ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)

// os_log is only supported when compiling with Xcode 8.
// Check if iOS version > 10 and the _os_log_internal symbol exists,
// load it dynamically and call it.
// Definitions extracted from #import <os/log.h>

#if OS_OBJECT_SWIFT3
OS_OBJECT_DECL_SWIFT(os_log);
#elif OS_OBJECT_USE_OBJC
OS_OBJECT_DECL(os_log);
#else
typedef struct os_log_s *os_log_t;
#endif /* OS_OBJECT_USE_OBJC */

extern struct os_log_s _os_log_default;

extern __attribute__((weak)) void _os_log_internal(void *dso, os_log_t log, int type, const char *message, ...);

// In iOS 10 NSLog only shows in device log when debugging from Xcode:
#define NSLog(FORMAT, ...) \
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"10.0")) {\
    void(*ptr_os_log_internal)(void *, __strong os_log_t, int, const char *, ...) = _os_log_internal;\
    if (ptr_os_log_internal != NULL) {\
        _Pragma("clang diagnostic push")\
        _Pragma("clang diagnostic error \"-Wformat\"")\
        _os_log_internal(&__dso_handle, OS_OBJECT_GLOBAL_OBJECT(os_log_t, _os_log_default), 0x00, [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);\
        _Pragma("clang diagnostic pop")\
    } else {\
        NSLog(FORMAT, ##__VA_ARGS__);\
    }\
} else {\
    NSLog(FORMAT, ##__VA_ARGS__);\
}

#endif /* PrefixHeader_pch */
Run Code Online (Sandbox Code Playgroud)

  • 这是一个很好的答案.确认它不是一个错误. (4认同)
  • @ishahak 我的目的是演示 `os_log` API 的使用。欢迎您根据需要编辑代码。 (3认同)

Tam*_*seh 9

这是iOS 10唯一的"功能".请改用:

printf("%s", [logString UTF8String]);
Run Code Online (Sandbox Code Playgroud)

  • 如果我需要打印NSDictionary怎么办?这太疯狂了. (3认同)