it-swarm-pt.tech

Como saber se o NSAssert está desabilitado nas compilações de versão?

Muitas vezes eu via "afirmar" no código do iOS, pesquisava no google e sabia que era verdade ou falso.

Quero saber se isso será desativado automaticamente no modo de liberação?

40
qichunren

Use NSAssert () e seus companheiros.

no projeto defina NS_BLOCK_ASSERTIONS para sua configuração de release.

Os tremplates do Xcode 4 desativam NSAsserts na configuração da versão. Acrescenta

-DNS_BLOCK_ASSERTIONS=1

para "Outros sinalizadores C" para "Liberar".

A partir da documentação:

As asserções serão desativadas se a macro do pré-processador NS_BLOCK_ASSERTIONS é definido.

A macro NSAssert avalia a condição e serve como um front end para o manipulador de asserções.

Cada encadeamento possui seu próprio manipulador de asserções, que é um objeto da classe NSAssertionHandler. Quando invocado, um manipulador de asserções imprime uma mensagem de erro que inclui os nomes de métodos e classes (ou o nome da função). Em seguida, gera uma exceção NSInternalInconsistencyException. Se a condição for avaliada como NÃO, a macro chama handleFailureInMethod:object:file:lineNumber:description: no manipulador de asserções do encadeamento atual, passando desc como a sequência de descrição.

Essa macro deve ser usada apenas nos métodos Objective-C.

40
zaph

Atualização: Verificada isso funciona no Xcode 8 também.

No Xcode 7, acesse as configurações de construção do projeto e pesquise "Assert" na barra de pesquisa. Isso mostra a seção "Apple LLVM 7.0 - Pré-processamento". Há uma configuração chamada "Ativar asserções de fundação".

Ativei/desabilitei com êxito o NSAssert a partir daí.

enter image description here

37
Jeff

Aqui vou fornecer uma meta-resposta:

@CocoaFu e @dasblinkenlight estão corretos. NS_BLOCK_ASSERTIONS Desativa NSAssert() e NDEBUG desativa assert(). Você precisa dos dois se usar os dois.

26
Rob Napier

Como Zaph disse -DNS_BLOCK_ASSERTIONS=1 está definido para lançamento. No entanto, se você quiser verificar isso.

Primeiro observe nos documentos que NSAssert está desativado pela macro NS_BLOCK_ASSERTIONS. Em seguida, adicione isso à compilação e observe que está em conformidade:

#ifdef NS_BLOCK_ASSERTIONS
#error Error - NS_BLOCK_ASSERTIONS is defined
#endif

Em seguida, altere o esquema para liberar (cmd - shift - <)

enter image description here

Em seguida, observe que a construção falha. Portanto NS_BLOCK_ASSERTIONS é definido, significando que NSAsserts estão desativados.

7
Robert

As declarações são compiladas condicionalmente a partir do seu código quando NDEBUG é definido. Se você definir NDEBUG=1 na seção de configurações de compilação correspondente, você desativará as declarações no seu código, independentemente do modo de liberação ou depuração.

5
dasblinkenlight

Aqui está o que eu faço na parte superior da minha main():

#if defined(NDEBUG)
{
  // The assertion code below should be compiled out of existence in a release
  // build.  Log an error and abort the program if it is not.
  bool ok = true;
  NSCAssert(ok = false, @"NS assertions should be disabled but are not");
  if (!ok)
  {
    NSLog(@"Detected release build but NS_BLOCK_ASSERTIONS is not defined");
    return -1;
  }
}
#endif

Observe que como main() é uma função C e não uma função Objective-C, NSCAssert é usada acima, em vez de NSAssert. (NSAssert espera que self seja válido.)

2
Todd Lehman

Agora, a partir do Xcode 6, a configuração é ENABLE_NS_ASSERTIONS, definido como 1 para configurações de depuração e 0 para Release, por padrão.

Você pode optar por versões da versão na linha de comando, passando o ENABLE_NS_ASSERTIONS=1 argumento, que estou fazendo para executar testes de unidade que verificam condições de asserção, mas, caso contrário, devem ser executados com o sinalizador DEBUG desativado.

0
Dov