iOS 10/Xcode 8中的NSLog设备似乎被截断了?为什么?;

iOS 10/Xcode 8中的NSLog设备似乎被截断了?为什么?;,ios,objective-c,xcode,ios10,xcode8,Ios,Objective C,Xcode,Ios10,Xcode8,为什么控制台输出在Xcode 8/iOS 10中显示不完整 这是仅限iOS 10的“功能”。改用这个: printf("%s", [logString UTF8String]); 作为临时解决方案,只需在全局头文件中将所有NSLOG重新定义为printf #define NSLog(FORMAT, ...) printf("%s\n", [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]); 在iOS 10上: pri

为什么控制台输出在Xcode 8/iOS 10中显示不完整

这是仅限iOS 10的“功能”。改用这个:

printf("%s", [logString UTF8String]);

作为临时解决方案,只需在全局头文件中将所有
NSLOG
重新定义为
printf

#define NSLog(FORMAT, ...) printf("%s\n", [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);
在iOS 10上:

  • printf()
    在Xcode的控制台内工作,但在设备的控制台日志上不工作
  • NSLog
    在两个位置截断
  • 我现在要做的是将我的
    NSLog
    字符串拆分成几行,并分别记录每一行

    - (void) logString: (NSString *) string
    {
        for (NSString *line in [string componentsSeparatedByCharactersInSet: [NSCharacterSet newlineCharacterSet]])
        {
            NSLog(@"%@", line);
        }
    }
    

    这可以在控制台上使用,但不容易阅读。

    您可以使用此方法。每800个字符分割一次。或者可以设置。 NSLOG我想每1000个字符截断一次。 如果字符串小于800,将使用简单的NSLog。 这对于Json长字符串非常有用,并使用控制台。 printf使用的是Xcode调试窗口,而不是控制台

        -(void) JSLog:(NSString*)logString{
    
                int stepLog = 800;
                NSInteger strLen = [@([logString length]) integerValue];
                NSInteger countInt = strLen / stepLog;
    
                if (strLen > stepLog) {
                for (int i=1; i <= countInt; i++) {
                    NSString *character = [logString substringWithRange:NSMakeRange((i*stepLog)-stepLog, stepLog)];
                    NSLog(@"%@", character);
    
                }
                NSString *character = [logString substringWithRange:NSMakeRange((countInt*stepLog), strLen-(countInt*stepLog))];
                NSLog(@"%@", character);
                } else {
    
                NSLog(@"%@", logString);
                }
    
        }
    
    -(void)JSLog:(NSString*)logString{
    int-stepLog=800;
    NSInteger strLen=[@([logString length])integerValue];
    NSInteger countInt=strLen/stepLog;
    如果(strLen>stepLog){
    
    对于(inti=1;i在iOS 10&Xcode 8中,苹果从旧的
    ASL
    (苹果系统日志)切换到一个名为
    Unified logging
    NSLog
    的新日志系统,调用实际上是委托给新的
    os\u Log
    API(来源:):

    重要

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

    重要

    当日志记录系统存储大于系统最大消息长度的日志消息行时,将截断。完整消息将被删除 使用log命令行工具查看实时数据流时可见 但是,请记住,流式日志数据是一种 昂贵的活动

    “系统最大消息长度”限制在SDK的标题中显示为1024个字符,用于格式化变量,如@Hot_Leaks所述(来源:
    ):

    由于缓冲区大小限制似乎是硬编码到
    libsystem\u trace.dylib
    ,我看不到解决方法,只能打印字符串文本而不是格式化变量(
    %@
    ),或者将格式化字符串变量拆分为<1024个字符串

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


    将xfdai的答案扩展到部署的应用程序

    在已部署的应用程序/非调试版本中,无法查看
    NSLog
    s或
    printf
    s

    将消息直接打印到设备日志(可以使用Xcode->Window->Devices、mac的控制台应用程序或第三方实用程序(如)访问)的唯一方法是调用
    os_log
    API(这是自iOS 10以来使用的
    ASL
    的后续版本)

    下面是一个全局头文件,我使用它在iOS 10上重新定义
    NSLog
    作为对
    \u os\u log\u internal
    的调用:

    #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 */
    
    \ifndef PrefixHeader\u pch
    #定义PrefixHeader\u pch
    #ifdef__OBJC__
    #进口
    #进口
    #恩迪夫
    #进口
    #进口
    /*
    *系统版本控制预处理器宏
    */
    #将系统版本定义为(v)([[[UIDevice currentDevice]systemVersion]比较:v选项:NSNumericSearch]==NSOrderedName)
    #定义系统版本\大于(v)([[[UIDevice currentDevice]systemVersion]比较:v选项:NSNumericSearch]==传感器降级)
    #将系统版本定义为大于或等于(v)([[UIDevice currentDevice]systemVersion]比较:v选项:NSNumericSearch]!=传感器解除搜索)
    #定义系统版本小于(v)([[[UIDevice currentDevice]systemVersion]比较:v选项:NSNumericSearch]==传感器解除搜索)
    #定义系统版本小于或等于(v)([[UIDevice currentDevice]系统版本]比较:v选项:NSNumericSearch]!=传感器降级)
    //只有在使用Xcode 8编译时才支持os_日志。
    //检查iOS版本是否大于10以及是否存在_os_log_内部符号,
    //动态加载它并调用它。
    //从#导入中提取的定义
    #如果OS_对象_SWIFT3
    操作系统对象(操作系统日志);
    #elif OS_OBJECT_USE_OBJC
    操作系统对象(操作系统日志);
    #否则
    typedef struct os_log_s*os_log_t;
    #endif/*OS\u OBJECT\u USE\u OBJC*/
    外部结构操作系统日志默认值;
    外部uuu属性uuu((弱))void u操作系统日志u内部(void*dso,操作系统日志u t log,int类型,常量字符*消息,…);
    //在iOS 10中,从Xcode调试时,NSLog仅显示在设备日志中:
    #定义NSLog(格式,…)\
    如果(系统版本大于或等于(@“10.0”)){\
    void(*ptr_os_log_internal)(void*,_强os_log_t,int,const char*,…)=_os_log_internal\
    如果(ptr_os_log_internal!=NULL){\
    _Pragma(“叮当声诊断推送”)\
    _杂注(“铿锵诊断错误\”-Wformat \”)\
    _os_log_internal(&__dso_handle,os_OBJECT_GLOBAL_OBJECT(os_log_t,_os_log_默认值),0x00,[[NSString stringWithFormat:FORMAT,##(u VA_参数)UTF8String])\
    _布拉格语(“叮当声诊断流行语”)\
    }否则{\
    NSLog(格式,###u VA_ARGS_uu)\
    }\
    }否则{\
    NSLog(格式,###u VA_ARGS_uu)\
    }
    #endif/*PrefixHeader\u pch*/
    
    这并不能提供很好的输出,但是p
    #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 */
    
    func Log(_ logString: String?) {
        if logString?.isEmpty ?? false { return }
        NSLog("%@", logString!)
        Log(String(logString!.dropFirst(1024)))
    }