Swift: print () vs println () vs NSLog ()

450

Qual é a diferença entre print, NSLoge printlne quando devo usar cada um?

Por exemplo, em Python, se eu quisesse imprimir um dicionário, eu simplesmente print myDict, mas agora tenho 2 outras opções. Como e quando devo usar cada um?

Do utilizador
fonte
1
possível duplicata da diferença entre println e print em Swift
Connor
2
que tal o NSLog e imprimir um NSDictionary não me fornece nada de útil?
Utilizador
Do iOS 10.0 em diante, é recomendável que você use os_log. Por favor, veja minha resposta abaixo .
HuaTham
Além de ver a documentação do Swift em os_log: tente ver a documentação completa da página do objetivo-C. É muito mais completo .
Querida

Respostas:

758

Algumas diferenças:

  1. printvs println:

    A printfunção imprime mensagens no console do Xcode ao depurar aplicativos.

    A printlné uma variação deste que foi removido em Swift 2 e não é usado qualquer mais. Se você vir o código antigo em uso println, agora poderá substituí-lo com segurança print.

    De volta ao Swift 1.x, printnão adicionava caracteres de nova linha no final da sequência impressa, ao contrário println. Mas hoje em dia, printsempre adiciona o caractere de nova linha no final da string e, se você não quiser fazer isso, forneça um terminatorparâmetro de "".

  2. NSLog:

    • NSLog é mais lento;

    • NSLogadiciona um carimbo de data e hora e identificador à saída, enquanto printque não;

    • NSLogAs instruções aparecem no console do dispositivo e no depurador, enquanto que printsomente no console do depurador.

    • NSLogusa printfseqüências de caracteres no estilo -style, por exemplo

      NSLog("%0.4f", CGFloat.pi)

      que produzirá:

      2017-06-09 11: 57: 55.642328-0700 MyApp [28937: 1751492] 3.1416

  3. A partir do iOS 10 / macOS 10.12, existe uma terceira alternativa, os_logparte do sistema "registro unificado" (consulte o vídeo do WWDC 2016 sobre registro unificado e rastreamento de atividades ).

    • Você deve importar os.logantes de usar a os_logfunção:

      import os.log
    • Como NSLog, também os_logemitirá mensagens para o console de depuração do Xcode e o console do dispositivo

    • Agora você pode controlar os campos "subsistema" e "categoria" disponíveis no aplicativo Console. Por exemplo:

      let log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "network")
      os_log("url = %@", log: log, url.absoluteString)

      Ao observar o aplicativo por meio do aplicativo externo do console, você pode não apenas adicionar essas colunas à visualização principal, mas também pode filtrar com base nelas. É muito útil quando você deseja diferenciar suas mensagens de depuração (a) daquelas geradas por outros subsistemas em nome do seu aplicativo; ou (b) mensagens de outras categorias ou tipos.

    • Você pode especificar diferentes tipos de mensagens de registro, seja .info, .debug, .error, .fault(ou .default):

      os_log("web service did not respond", type: .error)

      Portanto, se você estiver usando o aplicativo Console externo, poderá optar por ver apenas as mensagens de determinadas categorias (por exemplo, apenas mostrar mensagens de depuração se escolher "Incluir mensagens de depuração" no menu "Ação" do console). Essas configurações também determinam muitos detalhes sutis de questões sobre se as coisas estão registradas no disco ou não. Veja o vídeo da WWDC para mais detalhes.

    • Você não pode usar a interpolação de string ao usar os_log. Por exemplo, você não pode fazer:

      os_log("foo \(url.absoluteString)")

      Você teria que fazer:

      os_log("url = %@", url.absoluteString)
    • Uma das razões para a limitação acima é oferecer suporte à privacidade dos dados. Tipos de dados primitivos (por exemplo, números) são públicos por padrão e objetos (por exemplo, cadeias) são privados por padrão. No exemplo anterior, em que você registrou o URL, se o aplicativo fosse invocado no próprio dispositivo e você estivesse assistindo no aplicativo Console do Mac, você veria:

      url = <privado>

      Se você quiser vê-lo em um dispositivo externo, precisará fazer:

      os_log("url = %{public}@", url.absoluteString)
    • Observe que NSLogagora usa o sistema de notificação unificado nos bastidores, mas com as seguintes advertências:

      • Você não pode controlar o subsistema, categoria ou tipo de log;

      • Não suporta configurações de privacidade.

Bottom line, printé suficiente para tarefas simples, mas NSLogé útil porque inclui informações de registro de data e hora para você.

O poder de os_logentrar em grande alívio ao depurar aplicativos iOS que precisam ser testados fora do Xcode. Por exemplo, ao testar processos de aplicativos iOS em segundo plano, como a busca em segundo plano, a conexão com o depurador Xcode altera o ciclo de vida do aplicativo . Portanto, você frequentemente desejará testar no dispositivo físico, executando o aplicativo a partir do próprio dispositivo, não iniciando o aplicativo no depurador do Xcode. O registro unificado permite que você assista às os_loginstruções do dispositivo iOS no aplicativo macOS Console.

Roubar
fonte
37
Bom resumo! Para adicionar um pouco mais: você pode passar um NSString para println, mas não NSLog; você pode adicionar args para o NSLog, mas não println; Às vezes, a interpolação de strings no estilo rápido trava no NSLog, mas não no println.
Bao Lei
2
uma observação interessante sobre a otimização do compilador Swift e o uso de print () medium.com/ios-os-x-development/…
Carl
@ Rob, se eu usar o print, ele aparecerá no console do depurador ou não? Ou devemos usar debugPrint?
1
Se você usar print, ele aparecerá na área de depuração do Xcode, assim como debugPrint. A única diferença é que printacaba chamando o descriptionmétodo do objeto e debugPrintchama debugDescription, que pode ser mais detalhado do que description.
Rob
@Honey, esse tópico de comentário foi sinalizado como excessivamente longo, então eu só queria lembrá-lo de que os comentários não são para discussões prolongadas ou sessões de depuração. Se você tem algo que pode ser perguntado como uma pergunta adequada ao formato Estouro de Pilha, faça -o como uma pergunta para que todos possam se beneficiar de suas respostas. Se não funcionar como uma pergunta, você precisará levar a discussão para o bate-papo. Reserve comentários apenas para pedir esclarecimentos ou fazer observações rápidas.
Cody Gray
80

Se você estiver usando o Swift 2 , agora só poderá usar print () para escrever algo na saída.

A Apple combinou as funções println () e print () em uma.

Atualizado para iOS 9

Por padrão, a função termina a linha impressa adicionando uma quebra de linha.

print("Hello Swift")

Exterminador do Futuro

Para imprimir um valor sem quebra de linha, passe uma string vazia como terminador

print("Hello Swift", terminator: "")

Separador

Agora você pode usar o separador para concatenar vários itens

print("Hello", "Swift", 2, separator:" ")

Ambos

Ou você pode combinar usando dessa maneira

print("Hello", "Swift", 2, separator:" ", terminator:".")
Jorge Casariego
fonte
5
appendNewlinetem um valor padrãotrue
Adam
1
No iOS (9.0) você precisa usar terminator : "", por exemplo,print("...", terminator: "")
Khotu Nam
A afirmação na sua primeira frase está incorreta. NSLog () ainda funciona, mesmo no mais recente 2.x Swift
Sebastian
62

Além disso, o Swift 2 possui debugPrint()(e CustomDebugStringConvertibleprotocolo)!

Não se esqueça do debugPrint()que funciona, print()mas é mais adequado para depuração .

Exemplos:

  • Cordas
    • print("Hello World!") torna-se Hello World
    • debugPrint("Hello World!")torna-se "Hello World"(aspas!)
  • Gamas
    • print(1..<6) torna-se 1..<6
    • debugPrint(1..<6) torna-se Range(1..<6)

Qualquer classe pode personalizar sua representação de string de depuração via CustomDebugStringConvertibleprotocolo.

Valentin Shergin
fonte
2
DebugPrintableO protocolo foi renomeado para CustomDebugStringConvertibleprotocolo .
Franklin Yu
Obrigado Franklin!
Valentin Shergin
Então, o Swift descriptioné debugDescriptioncomo o Python stré repr?
usar o seguinte
Acho que sim.
Valentin Shergin
39

Para adicionar à resposta de Rob, desde o iOS 10.0, a Apple introduziu um sistema de "Unified Logging" inteiramente novo que substitui os sistemas de log existentes (incluindo ASL e Syslog, NSLog) e também supera as abordagens de log existentes no desempenho, graças a suas novas técnicas, incluindo compactação de dados de log e coleta de dados adiada.

Da Apple :

O sistema de log unificado fornece uma API única, eficiente e de alto desempenho para capturar mensagens em todos os níveis do sistema. Este sistema unificado centraliza o armazenamento de dados de log na memória e em um armazenamento de dados em disco.

A Apple recomenda o uso os_logdaqui para frente para registrar todos os tipos de mensagens, incluindo informações, depuração, mensagens de erro por causa de seu desempenho muito melhorado em comparação com os sistemas de registro anteriores e sua coleta centralizada de dados, permitindo uma inspeção conveniente dos registros e atividades dos desenvolvedores. De fato, o novo sistema provavelmente é tão baixo que não causa o "efeito de observador" onde seu erro desaparece se você inserir um comando de registro, interferindo no tempo do erro.

Desempenho do rastreamento de atividades, agora parte do novo sistema de registro unificado

Você pode aprender mais sobre isso em detalhes aqui .

Para resumir: use print()para sua depuração pessoal por conveniência (mas a mensagem não será registrada quando implantada nos dispositivos do usuário). Em seguida, use o Unified Logging ( os_log) o máximo possível para todo o resto.

HuaTham
fonte
5

Há outro método chamado dump()que também pode ser usado para o log:

func dump<T>(T, name: String?, indent: Int, maxDepth: Int, maxItems: Int)

Despeja o conteúdo de um objeto usando seu espelho na saída padrão.

Das funções da biblioteca padrão Swift

JAL
fonte