Macros de pré-processador são realmente ótimas para depuração. Não há nada errado com o NSLog (), mas é simples definir sua própria função de log com melhor funcionalidade. Aqui está o que eu uso, ele inclui o nome do arquivo e o número da linha para facilitar o rastreamento de instruções de log.
#define DEBUG_MODE
#ifdef DEBUG_MODE
#define DebugLog( s, ... ) NSLog( @"<%p %@:(%d)> %@", self, [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__] )
#else
#define DebugLog( s, ... )
#endif
Achei mais fácil colocar essa declaração inteira no cabeçalho do prefixo do que em seu próprio arquivo. Você poderia, se quisesse, criar um sistema de log mais complicado, fazendo o DebugLog interagir com objetos Objective-C normais. Por exemplo, você pode ter uma classe de log que grava em seu próprio arquivo de log (ou banco de dados) e inclui um argumento de 'prioridade' que você pode definir em tempo de execução, para que as mensagens de depuração não sejam mostradas na versão de lançamento, mas as mensagens de erro ( se você fez isso, poderá criar DebugLog (), WarningLog () e assim por diante).
Ah, lembre-se de que #define DEBUG_MODE
pode ser reutilizado em diferentes locais do seu aplicativo. Por exemplo, no meu aplicativo, eu o uso para desativar as verificações de chave de licença e permitir que o aplicativo seja executado somente antes de uma determinada data. Isso me permite distribuir uma cópia beta totalmente funcional e com tempo limitado, com o mínimo esforço da minha parte.