NSLog имя метода с Objective-C в iPhone

134

В настоящее время мы сами определяем расширенный механизм журнала, чтобы распечатать имя класса и номер строки исходного кода журнала.

#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, но иногда я также хочу выполнить отладку, выйдя из системы.

  • 0
    В моем последнем проекте iPhone я фактически сделал это вручную. Хотелось бы увидеть ответ на это.
  • 0
    Возможный дубликат: stackoverflow.com/questions/969130/…
Теги:
iphone
debugging

6 ответов

233
Лучший ответ
print(__FUNCTION__) // Swift
NSLog(@"%@", NSStringFromSelector(_cmd)); // Objective-C

Swift 3 и выше

print(#function)
  • 119
    Вы действительно должны использовать NSLog(@"%@", NSStringFromSelector(_cmd)) , если вы собираетесь использовать _cmd , поскольку AFAIK Apple объявляет _cmd как тип SEL , а не как C-строку. Тот факт, что он реализован в виде C-строки (в текущих версиях Mac OS X и iPhone OS), не означает, что вы должны использовать его таким образом, поскольку Apple может изменить его в обновлении ОС.
  • 5
    Да, NSStringFromSelector - более правильный ответ. Я никогда не использую _cmd как строку c для чего-либо, кроме кода отладки.
Показать ещё 3 комментария
150

Чтобы технически ответить на ваш вопрос, вы хотите:

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

Или вы также можете сделать:

NSLog(@"%s", __PRETTY_FUNCTION__);
  • 2
    С __FUNCTION__ и его довольно эквивалентом также доступно в C-функциях.
  • 0
    NB __FUNCTION__ также включает в себя имя класса
Показать ещё 1 комментарий
75

ТЛ; др

NSLog( @"ERROR %@ METHOD %s:%d ", @"DescriptionGoesHere", __func__, __LINE__ );

подробности

У Apple есть техническая страница вопросов и ответов: QA1669 - Как я могу добавить контекстную информацию - такую как текущий метод или номер строки - в свои операторы регистрации?

Чтобы помочь с регистрацией:

  • Препроцессор C предоставляет несколько макросов.
  • Objective-C предоставляет выражения (методы).
    • Передайте неявный аргумент для текущего селектора метода: _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") одним из двух способов, как описано в этом сообщении блога Кодека:

  • Используя Objective-C вызов NSStringFromSelector:
    NSLog(@"%@", NSStringFromSelector(selector) );
  • Используя прямой C:
    NSLog(@"%s", selector );

Эта информация взята со ссылочной страницы Apple Doc по состоянию на 2013-07-19. Эта страница была в последний раз обновлена 2011-10-04.

  • 1
    Для C используйте sel_getName(SEL) поскольку SEL является непрозрачным типом и не всегда может быть char *
8
NSLog(@"%@", NSStringFromSelector(_cmd)); // Objective-C
print(__FUNCTION__) // Swift
  • 4
    Для тех, кто сталкивается с этим ответом в будущем: он эквивалентен принятому ответу, но принятый ответ был другим, когда этот был опубликован (принятый ответ был отредактирован в 2014 году). Я собирался проголосовать вниз, но после небольшого расследования проголосовал вместо этого :)
0

В Swift 4:

func test() {

print(#function)

}

test()//напечатать значение "test()"

0

Это на самом деле так же просто, как:

printf(_cmd);

По какой-то причине iOS позволяет передавать _cmd как литерал char, даже не предупреждая о компиляции. Кто знает

Ещё вопросы

Сообщество Overcoder
Наверх
Меню