В настоящее время мы сами определяем расширенный механизм журнала, чтобы распечатать имя класса и номер строки исходного кода журнала.
#define NCLog(s, ...) NSLog(@"<%@:%d> %@", [[NSString stringWithUTF8String:__FILE__] lastPathComponent], \
__LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__])
Например, когда я звоню NCLog (@"Hello world"); Выход будет:
<ApplicationDelegate:10>Hello world
Теперь я также хочу выйти из имени метода, как:
<ApplicationDelegate:applicationDidFinishLaunching:10>Hello world
Таким образом, это сделает нашу отладку проще, когда мы сможем узнать, какой метод вызывается. Я знаю, что у нас также есть отладчик Xcode, но иногда я также хочу выполнить отладку, выйдя из системы.
print(__FUNCTION__) // Swift
NSLog(@"%@", NSStringFromSelector(_cmd)); // Objective-C
Swift 3 и выше
print(#function)
NSLog(@"%@", NSStringFromSelector(_cmd))
, если вы собираетесь использовать _cmd
, поскольку AFAIK Apple объявляет _cmd
как тип SEL
, а не как C-строку. Тот факт, что он реализован в виде C-строки (в текущих версиях Mac OS X и iPhone OS), не означает, что вы должны использовать его таким образом, поскольку Apple может изменить его в обновлении ОС.
Чтобы технически ответить на ваш вопрос, вы хотите:
NSLog(@"<%@:%@:%d>", NSStringFromClass([self class]), NSStringFromSelector(_cmd), __LINE__);
Или вы также можете сделать:
NSLog(@"%s", __PRETTY_FUNCTION__);
__FUNCTION__
и его довольно эквивалентом также доступно в C-функциях.
__FUNCTION__
также включает в себя имя класса
NSLog( @"ERROR %@ METHOD %s:%d ", @"DescriptionGoesHere", __func__, __LINE__ );
У Apple есть техническая страница вопросов и ответов: QA1669 - Как я могу добавить контекстную информацию - такую как текущий метод или номер строки - в свои операторы регистрации?
Чтобы помочь с регистрацией:
_cmd
Как указано в других ответах, чтобы просто получить текущее имя метода, вызовите:
NSStringFromSelector(_cmd)
Чтобы получить имя текущего метода и номер текущей строки, используйте эти два макроса __func__
и __LINE__
как показано здесь:
NSLog(@"%s:%d someObject=%@", __func__, __LINE__, someObject);
Другой пример... Фрагменты кода, которые я храню в библиотеке фрагментов кода Xcode:
NSLog( @"ERROR %@ METHOD %s:%d ", @"DescriptionGoesHere", __func__, __LINE__ );
... и TRACE вместо ERROR...
NSLog( @"TRACE %@ METHOD %s:%d ", @"DescriptionGoesHere", __func__, __LINE__ );
… И более длинный, использующий мягкое описание, передающее значение ([rows count]
)…
NSLog( @"TRACE %@ METHOD %s:%d.", [NSString stringWithFormat:@"'Table of Contents.txt' file count of Linefeed-delimited rows: %u.", [rows count]] , __func__, __LINE__ );
Обратите внимание на использование пары символов подчеркивания по обе стороны макроса.
| 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 class name [[NSString %@ Source code file name stringWithUTF8String:__FILE__] lastPathComponent] [NSThread callStackSymbols] %@ NSArray of stack trace
Некоторые каркасы журналирования также могут помочь в получении текущего метода или номера строки. Я не уверен, так как я использовал отличный каркас для ведения журналов в Java (SLF4J + LogBack), но не в Cocoa.
См. Этот вопрос для ссылок на различные каркасы журналов Cocoa.
Если у вас есть переменная Selector (SEL), вы можете напечатать имя ее метода ("message") одним из двух способов, как описано в этом сообщении блога Кодека:
NSLog(@"%@", NSStringFromSelector(selector) );
NSLog(@"%s", selector );
Эта информация взята со ссылочной страницы Apple Doc по состоянию на 2013-07-19. Эта страница была в последний раз обновлена 2011-10-04.
sel_getName(SEL)
поскольку SEL является непрозрачным типом и не всегда может быть char *
NSLog(@"%@", NSStringFromSelector(_cmd)); // Objective-C
print(__FUNCTION__) // Swift
В Swift 4:
func test() {
print(#function)
}
test()//напечатать значение "test()"
Это на самом деле так же просто, как:
printf(_cmd);
По какой-то причине iOS позволяет передавать _cmd как литерал char, даже не предупреждая о компиляции. Кто знает
iPhone
я фактически сделал это вручную. Хотелось бы увидеть ответ на это.