NSLog里面干了啥?(摘自GNUStep)
NSLog的实现
void NSLog(NSString* format, ...)
{
va_list ap;
va_start(ap, format);
NSLogv(format, ap);
va_end(ap);
}
NSLogv()函数主要拼接了系统打印时间、线程信息以及要打印函数传入的参数(真正要打印的东西)
void NSLogv(NSString* format, va_list args)
{
NSMutableString *prefix;
NSString *message;
NSString *threadName = nil;
NSThread *t = nil;
ger tid = GSPrivateThreadID();
static int pid = 0;
if (_NSLog_printf_handler == NULL)
{
_NSLog_printf_handler = *_NSLog_standard_printf_handler;
}
if (pid == 0)
{
pid = (int)getpid();
}
if (GSPrivateDefaultsFlag(GSLogThread) == YES)
{
t = GSCurrentThread();
threadName = [t name];
}
prefix = [[NSMutableString alloc] initWithCapacity: 1000];
NSString *fmt;
NSString *cal;
if (GSPrivateDefaultsFlag(GSLogOffset) == YES)
{
fmt = @"%Y-%m-%d %H:%M:%S.%F %z";
}
else
{
fmt = @"%Y-%m-%d %H:%M:%S.%F";
}
cal = [[NSCalendarDate calendarDate] descriptionWithCalendarFormat: fmt];
// 拼接系统日期
[prefix appendString: cal];
[prefix appendString: @" "];
[prefix appendString: [[NSProcessInfo processInfo] processName]];
if (nil == t || ((NSThread*)tid == t && nil == threadName))
{
[prefix appendFormat: @"[%d:%"PRIuPTR"] ",
pid, tid];
}
else if (nil == threadName)
{
[prefix appendFormat: @"[%d:%"PRIuPTR",%p] ",
pid, tid, t];
}
else
{
[prefix appendFormat: @"[%d:%"PRIuPTR",%@] ",
pid, tid, threadName];
}
message = [[NSString alloc] initWithFormat: format arguments: args];
[prefix appendString: message];
[message release];
if ([prefix hasSuffix: @"\n"] == NO)
{
[prefix appendString: @"\n"];
}
if (nil == myLock)
{
GSLogLock();
}
// 直接用函数指针调用函数,采用递归锁保证线程同步安全
(*lockImp)(myLock, @selector(lock));
_NSLog_printf_handler(prefix);
(*unlockImp)(myLock, @selector(unlock));
[prefix release];
}
// 将打印的字符串采用UTF-8编码写入NSData流,并通过write函数写入handle所指的文档
static void _NSLog_standard_printf_handler(NSString* message)
{
NSData *d;
const char *buf;
unsigned len;
static NSStringEncoding enc = 0;
if (enc == 0)
{
enc = [NSString defaultCStringEncoding];
}
// 将字符串采用UTF-8编码写入NSData流
d = [message dataUsingEncoding: enc allowLossyConversion: NO];
if (d == nil)
{
d = [message dataUsingEncoding: NSUTF8StringEncoding
allowLossyConversion: NO];
}
if (d == nil) // Should never happen.
{
buf = [message lossyCString];
len = strlen(buf);
}
else
{
buf = (const char*)[d bytes];
len = [d length];
}
// 将要输出的信息写入文件
write(_NSLogDescriptor, buf, len);
}
总结:NSLog函数本质上就将输入的参数拼接成字符串转成NSData流后调用wirte函数写入handle所指的文档
(限于水平,本文可能存在瑕疵甚至错误的地方。如有发现,还请留言指正,相互学习。thx! )
KEEP LOOKING, DON`T SETTLE!

浙公网安备 33010602011771号