目前,我正在为我的项目构建两个应用程序,一个是发行版和版本。另一个在调试中(唯一改变的是用于签名和端点的配置文件)。由于某些策略,我不应该在本地创建ipa文件。所以我使用maven来构建这两个版本(发布和调试),基于脚本。由于相同的策略,应该从应用程序(NSLog
,printf ...)中完全删除输出。 我知道预处理器宏,但我不想依赖它们,因为某人(不知道)可能会改变它们并危及我想要实现的目标。所以我想要的是:
NSLogs
被剥离或禁用。 Maven依赖远程存储库中的内容实际进行构建,因此如果有一种方法可以在远程repo提交期间禁用此日志,那么它也是一个解决方案..
答案 0 :(得分:2)
使用此宏,它将自动关闭登录发布模式。
只需将所有NSLog
替换为DLog
,并在将来使用DLog
进行日志记录。
示例:DLog(@"Text : %@",sometext);
#ifdef DEBUG
# define DLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
# define DLog(...)
#endif
答案 1 :(得分:1)
这是一个有趣的请求,但如果您愿意为每个被跳过的日志接受一些函数调用开销,那么这是可行的。 EtPanKit framework内部有一个很好的功能,用于检查尝试调用日志函数的文件是否与Info.plist
文件中的预定义类数组匹配。除了是一个出色的调试过滤器之外,您在发布时需要做的就是从plist中删除所有键,或者在Release版本中指定一个不同的键,而不使用与LEPLogEnabledFilenames
键相关联的值。 / p>
为了防止链接腐烂,这里是函数本身和相关的宏,使它调用更漂亮:
#define LEPLogStack(...) LEPLogInternal(__FILE__, __LINE__, 1, __VA_ARGS__)
#define LEPLog(...) LEPLogInternal(__FILE__, __LINE__, 0, __VA_ARGS__)
#import <Foundation/Foundation.h>
#import <libgen.h>
#import <time.h>
#import <sys/time.h>
#include <execinfo.h>
#include <pthread.h>
static NSSet * enabledFilesSet = nil;
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
void LEPLogInternal(const char * filename, unsigned int line, int dumpStack, NSString * format, ...)
{
va_list argp;
NSString * str;
NSAutoreleasePool * pool;
char * filenameCopy;
char * lastPathComponent;
struct timeval tv;
struct tm tm_value;
//NSDictionary * enabledFilenames;
pool = [[NSAutoreleasePool alloc] init];
pthread_mutex_lock(&lock);
if (enabledFilesSet == nil) {
enabledFilesSet = [[NSSet alloc] initWithArray:[[NSUserDefaults standardUserDefaults] arrayForKey:LEPLogEnabledFilenames]];
}
pthread_mutex_unlock(&lock);
NSString * fn;
fn = [[NSFileManager defaultManager] stringWithFileSystemRepresentation:filename length:strlen(filename)];
fn = [fn lastPathComponent];
if (![enabledFilesSet containsObject:fn]) {
[pool release];
return;
}
va_start(argp, format);
str = [[NSString alloc] initWithFormat:format arguments:argp];
va_end(argp);
NSString * outputFileName = [[NSUserDefaults standardUserDefaults] stringForKey:LEPLogOutputFilename];
static FILE * outputfileStream = NULL;
if ( ( NULL == outputfileStream ) && outputFileName )
{
outputfileStream = fopen( [outputFileName UTF8String], "w+" );
}
if ( NULL == outputfileStream )
outputfileStream = stderr;
gettimeofday(&tv, NULL);
localtime_r(&tv.tv_sec, &tm_value);
fprintf(outputfileStream, "%04u-%02u-%02u %02u:%02u:%02u.%03u ", tm_value.tm_year + 1900, tm_value.tm_mon + 1, tm_value.tm_mday, tm_value.tm_hour, tm_value.tm_min, tm_value.tm_sec, tv.tv_usec / 1000);
//fprintf(stderr, "%10s ", [[[NSDate date] description] UTF8String]);
fprintf(outputfileStream, "[%s:%u] ", [[[NSProcessInfo processInfo] processName] UTF8String], [[NSProcessInfo processInfo] processIdentifier]);
filenameCopy = strdup(filename);
lastPathComponent = basename(filenameCopy);
fprintf(outputfileStream, "(%s:%u) ", lastPathComponent, line);
free(filenameCopy);
fprintf(outputfileStream, "%s\n", [str UTF8String]);
[str release];
if (dumpStack) {
void * frame[128];
int frameCount;
int i;
frameCount = backtrace(frame, 128);
for(i = 0 ; i < frameCount ; i ++) {
fprintf(outputfileStream, " %p\n", frame[i]);
}
}
if ( outputFileName )
{
fflush(outputfileStream);
}
[pool release];
}
答案 2 :(得分:1)
我知道您不想依赖预处理器宏,但有一种简单的方法可以使用预处理器删除任何NSLog语句:
在您的前缀标题中添加以下内容:
#ifndef DEBUG
#define NSLog(...)
#endif
如果未定义DEBUG,则预处理器将在整个应用程序代码中删除所有NSLog语句。 如果未在构建设置中自动添加DEBUG,则只需添加#define DEBUG语句,并在构建版本时将其注释掉。
对printf()语句也可以这样做。
我已经在我发布的应用程序中成功使用了它,以便摆脱NSLog的发布。
答案 3 :(得分:0)
您可以添加如下完整的日志系统:
#ifndef Logs_h
#define Logs_h
/* Log levels */
#define LOG_LEVEL_NO_LOG 0
#define LOG_LEVEL_ONLY_ERRORS 1
#define LOG_LEVEL_ERROS_AND_WARNINGS 2
#define LOG_LEVEL_LOG_ALL 3
/* Log levels */
#ifdef DEBUG
#define LOG_LEVEL LOG_LEVEL_LOG_ALL /* <-- Change The Log Level here */
#else
#define LOG_LEVEL LOG_LEVEL_NO_LOG /* No logs on release now */
#endif
/* Logs Macros */
#if LOG_LEVEL >= LOG_LEVEL_LOG_ALL
#define DebugLog(fmt, ...) NSLog(@"[Debug] %s [Line %d]: " fmt, __PRETTY_FUNCTION__, __LINE__, ## __VA_ARGS__)
#else
#define DebugLog(...) /* */
#endif
#if LOG_LEVEL >= LOG_LEVEL_ERROS_AND_WARNINGS
#define WarnLog(fmt, ...) NSLog(@"[Warning] %s [Line %d]: " fmt, __PRETTY_FUNCTION__, __LINE__, ## __VA_ARGS__)
#else
#define WarnLog(...) /* */
#endif
#if LOG_LEVEL >= LOG_LEVEL_ONLY_ERRORS
#define ErrorLog(fmt, ...) NSLog(@"[Error] %s [Line %d]: " fmt, __PRETTY_FUNCTION__, __LINE__, ## __VA_ARGS__)
#else
#define ErrorLog(...) /* */
#endif
#endif