objective-c - downloads - ios development



NSLog o nome do método com Objective-C no iPhone (4)

Atualmente, estamos definindo um mecanismo de log estendido para imprimir o nome da classe e o número da linha de origem do log.

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

Por exemplo, quando eu chamo NCLog (@ "Hello world"); A saída será:

<ApplicationDelegate:10>Hello world

Agora eu também quero sair do nome do método como:

<ApplicationDelegate:applicationDidFinishLaunching:10>Hello world

Então, isso tornaria nossa depuração mais fácil quando pudermos saber qual método está sendo chamado. Eu sei que nós também temos o depurador Xcode, mas às vezes, eu também quero depurar fazendo logout.


Answer #1

tl; dr

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

Detalhes

A Apple tem uma página de perguntas e respostas técnicas: QA1669 - Como posso adicionar informações de contexto - como o método ou número de linha atual - às minhas instruções de log?

Para ajudar no registro:

  • O pré-processador C fornece algumas macros .
  • Objective-C fornece expressões (métodos).
    • Passe o argumento implícito para o seletor do método atual: _cmd

Como outras respostas indicadas, para simplesmente obter o nome do método atual, chame:

NSStringFromSelector(_cmd)

Para obter o nome do método atual e o número da linha atual, use estas duas macros __func__ e __LINE__ como visto aqui:

NSLog(@"%s:%d someObject=%@", __func__, __LINE__, someObject);

Outro exemplo… Snippets de código que eu guardo na biblioteca de snippets de código do Xcode:

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

… E TRACE em vez de ERROR…

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

… E um mais longo usando uma descrição codificada passando um valor ( [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__ );

Macros de pré-processador para log

Observe o uso de um par de caracteres de sublinhado ao redor de ambos os lados da macro.

| 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. 

Expressões para log

| 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

Estruturas de registro

Algumas estruturas de registro podem ajudar a obter o método atual ou o número de linha também. Não tenho certeza, pois usei uma ótima estrutura de logging em Java ( SLF4J + LogBack ), mas não em Cocoa.

Veja esta questão para links para vários frameworks de logging do Cocoa.

Nome do Seletor

Se você tiver uma variável Selector (um SEL ), poderá imprimir o nome do método ("message") de duas maneiras, conforme descrito neste post do blog do Codec :

  • Usando a chamada Objective-C para NSStringFromSelector :
    NSLog(@"%@", NSStringFromSelector(selector) );
  • Usando direto C:
    NSLog(@"%s", selector );

Essas informações são extraídas da página de documentos da Apple vinculada em 2013-07-19. Essa página foi atualizada pela última vez em 2011-10-04.


Answer #2

Na verdade, é tão simples quanto:

printf(_cmd);

Por alguma razão, o iOS permite que o _cmd seja passado como um caracter literal, mesmo sem um aviso de compilação. Quem sabe


Answer #3

Para responder tecnicamente à sua pergunta, você deseja:

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

Ou você também pode fazer:

NSLog(@"%s", __PRETTY_FUNCTION__);

Answer #4
print(__FUNCTION__) // Swift
NSLog(@"%@", NSStringFromSelector(_cmd)); // Objective-C

Swift 3 e acima

print(#function)




debugging