NSLog使用Objective-C在iPhone中记录方法名称

vod*_*ang 147 c iphone debugging objective-c

目前,我们正在定义一个扩展日志机制来打印出日志的类名和源行号.

#define NCLog(s, ...) NSLog(@"<%@:%d> %@", [[NSString stringWithUTF8String:__FILE__] lastPathComponent], \
    __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__])
Run Code Online (Sandbox Code Playgroud)

例如,当我调用NCLog(@"Hello world")时; 输出将是:

<ApplicationDelegate:10>Hello world
Run Code Online (Sandbox Code Playgroud)

现在我还想注销方法名称,如:

<ApplicationDelegate:applicationDidFinishLaunching:10>Hello world
Run Code Online (Sandbox Code Playgroud)

因此,当我们知道调用哪种方法时,这将使我们的调试变得更容易.我知道我们也有Xcode调试器,但有时候,我也希望通过注销来进行调试.

dra*_*ard 255

print(__FUNCTION__) // Swift
NSLog(@"%@", NSStringFromSelector(_cmd)); // Objective-C
Run Code Online (Sandbox Code Playgroud)

斯威夫特3及以上

print(#function)
Run Code Online (Sandbox Code Playgroud)

  • 你真的应该使用`NSLog(@"%@",NSStringFromSelector(_cmd))`,如果你要使用`_cmd`,因为AFAIK Apple将`_cmd`声称为'SEL`类型,而不是C字符串.仅仅因为它恰好被实现为C字符串(当前版本的Mac OS X和iPhone OS)并不意味着您应该以这种方式使用它,因为Apple可以在操作系统更新中更改它. (120认同)
  • 是的,NSStringFromSelector是更正确的答案.除了调试代码之外,我从不使用_cmd作为c字符串. (5认同)
  • 方法调用如`[self doSomething:arg1 somethingElse:arg2]`被转换为C函数调用`objc_msgSend(self,"doSomething:somethingElse:,arg1,arg2);`.第二个参数`objc_msgSend()` `char*`.请记住,因为Objective-C运行时是动态的,所以它实际上使用查找表来确定调用哪个类的方法,因此char*很方便,因为方法在查找表中表示为字符串. (3认同)

Dav*_*ong 158

要从技术上回答您的问题,您需要:

NSLog(@"<%@:%@:%d>", NSStringFromClass([self class]), NSStringFromSelector(_cmd), __LINE__);
Run Code Online (Sandbox Code Playgroud)

或者您也可以这样做:

NSLog(@"%s", __PRETTY_FUNCTION__);
Run Code Online (Sandbox Code Playgroud)

  • 使用`__FUNCTION__`并且它在C函数中也很有用. (2认同)

Bas*_*que 79

TL;博士

NSLog( @"ERROR %@ METHOD %s:%d ", @"DescriptionGoesHere", __func__, __LINE__ );
Run Code Online (Sandbox Code Playgroud)

细节

Apple有一个技术问答页面:QA1669 - 如何在我的日志记录语句中添加上下文信息(例如当前方法或行号)?

协助记录:

  • C预处理器提供了一些.
  • Objective-C提供表达式(方法).
    • 传递当前方法的选择器的隐式参数:_cmd

正如其他答案所示,仅仅获取当前方法的名称,请致电:

NSStringFromSelector(_cmd)
Run Code Online (Sandbox Code Playgroud)

要获取当前方法名称当前行号,请使用这两个宏__func__,__LINE__如下所示:

NSLog(@"%s:%d someObject=%@", __func__, __LINE__, someObject);
Run Code Online (Sandbox Code Playgroud)

另一个例子......我在Xcode的代码片段库中保存的代码片段:

NSLog( @"ERROR %@ METHOD %s:%d ", @"DescriptionGoesHere", __func__, __LINE__ );
Run Code Online (Sandbox Code Playgroud)

......和TRACE而不是ERROR ......

NSLog( @"TRACE %@ METHOD %s:%d ", @"DescriptionGoesHere", __func__, __LINE__ );
Run Code Online (Sandbox Code Playgroud)

...以及使用软编码描述传递值([rows count])的较长的...

NSLog( @"TRACE %@ METHOD %s:%d.", [NSString stringWithFormat:@"'Table of Contents.txt' file's count of Linefeed-delimited rows: %u.", [rows count]] , __func__, __LINE__ );
Run Code Online (Sandbox Code Playgroud)

用于记录的预处理器宏

请注意在宏的两侧使用一对下划线字符.

| Macro                | Format   | Description
  __func__               %s         Current function signature
  __LINE__               %d         Current line number
  __FILE__               %s         Full path to source file
  __PRETTY_FUNCTION__    %s         Like __func__, but includes verbose
                                    type information in C++ code. 

记录的表达式

| Expression                       | Format   | Description
  NSStringFromSelector(_cmd)         %@         Name of the current selector
  NSStringFromClass([self class])    %@         Current object's class name
  [[NSString                         %@         Source code file name
    stringWithUTF8String:__FILE__]   
    lastPathComponent] 
  [NSThread callStackSymbols]        %@         NSArray of stack trace

记录框架

一些日志框架可能有助于获取当前方法或行号.我不确定,因为我在Java中使用了一个很棒的日志框架(SLF4J + LogBack)而不是Cocoa.

有关各种Cocoa日志框架的链接,请参阅此问题.

选择器的名称

如果您有一个Selector变量(SEL),您可以按照此Codec 博客文章所描述的两种方式之一打印其方法名称("message"):

  • 使用Objective-C调用NSStringFromSelector:
    NSLog(@"%@", NSStringFromSelector(selector) );
  • 使用直C:
    NSLog(@"%s", selector );

此信息来自链接的Apple文档页面,截至2013-07-19.该页面最后更新2011-10-04.


Huy*_*Inc 8

NSLog(@"%@", NSStringFromSelector(_cmd)); // Objective-C
print(__FUNCTION__) // Swift
Run Code Online (Sandbox Code Playgroud)

  • 对于将来遇到此答案的任何人:它等同于接受的答案,但是当发布此答案时,接受的答案是不同的(已接受的答案在2014年编辑).我即将投票,但经过一次小规模的调查投票反而:) (4认同)