iOS 10/Xcode 8中的NSLog设备似乎被截断了?为什么?;
为什么控制台输出在Xcode 8/iOS 10中显示不完整 这是仅限iOS 10的“功能”。改用这个: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
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)))
}