Como faço para testar se uma string está vazia no Objective-C?

651

Como faço para testar se um NSStringestá vazio no Objective-C?

Jamey McElveen
fonte

Respostas:

1156

Você pode verificar se [string length] == 0. Isso verificará se é uma sequência válida, mas vazia (@ "") e se é nula, pois a chamada lengthnil também retornará 0.

Marc Charbonneau
fonte
12
Existem algumas NSStrings muito raras nas quais isso resultará em falso negativo (dizendo que a string não está vazia, quando, por motivos práticos, está). Considere @"\u200B"(consistindo apenas no caractere Unicode ZERO WIDTH SPACE . A impressão imprimirá 0 caracteres (verifique usando fonte monoespaçada), mas string.length fornecerá 1. Existem outros caracteres Unicode (como OBJECT REPLACEMENT CHARACTER ) que se comportam da mesma forma. obter o último ao analisar texto PDF.
fzwo
43
@fzwo não é um burro, mas em teoria não dá um falso negativo. Ele se comporta exatamente como você esperaria. Sua interpretação do que ZERO WIDTH SPACEé realmente não importa, porque, apesar disso , @"\u200B" é um caractere; portanto, se você testar a seqüência de caracteres vazia, ela dirá que não é porque existe um caractere. Apenas não é possível imprimir seguindo o padrão Unicode.
bmeulmeester
2
Claro que é tecnicamente correto, não estou debatendo isso. Eu só quero advertir que isso pode não exibir o comportamento pretendido ou esperado, e foi por isso que escrevi "para fins práticos". Depende do significado pretendido de "vazio".
fzwo
4
Não é um falso negativo. Um "espaço de valor zero" é um caractere unicode como qualquer outro. É apenas "vale a pena lembrar" se relevante para o seu aplicativo. (Grande pensamento, fzwo!)
Fattie
2
Deixe-me saber se eu estiver errado, mas acho que você também poderia omitir == 0 parte e adicionar uma negação na frente: ![string length]. Parece mais limpo.
Damirstuhec 31/08/14
126

A resposta de Marc está correta. Mas aproveito a oportunidade para incluir um ponteiro para a generalização de Wil Shipley isEmpty, que ele compartilhou em seu blog :

static inline BOOL IsEmpty(id thing) {
return thing == nil
|| ([thing respondsToSelector:@selector(length)]
&& [(NSData *)thing length] == 0)
|| ([thing respondsToSelector:@selector(count)]
&& [(NSArray *)thing count] == 0);
}
Matt G
fonte
26
Se você deseja que isso seja muito generalizado, pode-se implementar essa lógica como uma categoria no NSObject em vez de usar um método estático, como mostrado aqui.
Brad The App Guy
16
Estranhamente, isso realmente não verifica [NSNull null].
23810 Peter N Lewis
14
Se você estiver em uma situação em que não sabe que tipo de objeto está verificando, acho que isso funciona. No entanto, sugiro que se você não souber se um objeto é NSData ou NSArray, você terá problemas maiores. Qual será a sua próxima macro após esta chamada, condenseToSingleNSData (id)? expandToNSArray (coisa de identificação)? Mais cedo ou mais tarde, você perguntará com que classe de classe está lidando, melhor fazê-lo na primeira referência.
Brane
1
@ BradSmith, pode-se criar uma categoria para ela, mas valores nulos não serão contados, pois o método não será chamado. Por exemplo, se thing = nil, [thing IsEmpty] não seria chamado e sempre retornaria false / NO. Para verificar se há nulo, é preciso haver um parâmetro. Objetos nulos não podem se comparar como nulos por meio de uma categoria.
Chris
3
@ Chris, em seguida, você pode alterar o método de categoria para -isNotEmpty:)
nielsbot
93

A primeira abordagem é válida, mas não funciona se sua string tiver espaços em branco ( @" "). Portanto, você deve limpar esses espaços em branco antes de testá-lo.

Este código limpa todos os espaços em branco nos dois lados da string:

[stringObject stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet] ];

Uma boa idéia é criar uma macro, para que você não precise digitar esta linha de monstro:

#define allTrim( object ) [object stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet] ]

Agora você pode usar:

NSString *emptyString = @"   ";

if ( [allTrim( emptyString ) length] == 0 ) NSLog(@"Is empty!");
Equipe de Desenvolvimento SEQOY
fonte
3
Por que usar macros quando não são necessárias? Nesse caso, qualquer tipo de segurança de segurança é sacrificada sem benefício real.
EM
É por conveniência simples, se você quiser escrever "[objeto stringObjeto objetoByTrimmingCharactersInSet: [NSCharacterSet whitespaceCharacterSet]]" "sempre que desejar verificar se uma sequência está vazia, é com você.
Equipe de desenvolvimento SEQOY
18
seria melhor servir uma NSStringcategoria que adiciona um método chamado trimmedStringque faz exatamente o que você escreveu.
Dave DeLong
2
Observe que a Apple whitespaceCharacterSetnão inclui novas linhas! Aqui está uma categoria que eu escrevi incluindo trime alguns outros métodos úteis: github.com/alexch/unsuck/blob/master/unsuck/NSString%2BUnsuck.m github.com/alexch/unsuck/blob/master/unsuckTests/…
AlexChaffee
@EM Não sou fã de macros, mas não entendo sua preocupação com a segurança de tipo. Durante a compilação, a macro é substituída por seu conteúdo; portanto, se você invocar a macro com algo diferente de um NSString, ainda receberá uma mensagem do compilador. Categorias seria muito melhor de qualquer maneira.
Zmaster
32

Uma das melhores soluções que eu já vi (melhor que a de Matt G) é essa função inline aprimorada que peguei em um repo do Git Hub (o de Wil Shipley, mas não consigo encontrar o link):

// Check if the "thing" passed is empty
static inline BOOL isEmpty(id thing) {
    return thing == nil
    || [thing isKindOfClass:[NSNull class]]
    || ([thing respondsToSelector:@selector(length)]
        && [(NSData *)thing length] == 0)
    || ([thing respondsToSelector:@selector(count)]
        && [(NSArray *)thing count] == 0);
}
Roubar
fonte
2
Este é o trabalho de Wil Shipley. FYI, você pode alterar [coisa isKindOfClass: [classe NSNull]] para apenas (coisa == [NSNull nulo])
Steve N
Ufa ... exatamente o que eu estava procurando. Eu estava ficando louco, tentando descobrir por que minha função "cellForRowAtIndexPath" estava travando devido a seqüências nulas (e não consegui entender o problema). Esta função resolveu perfeitamente.
9135 Mike Gledhill
Cópia do comentário do @Brane: Se você está em uma situação em que não sabe que tipo de objeto está verificando, acho que isso funciona. No entanto, sugiro que se você não souber se um objeto é NSData ou NSArray, você terá problemas maiores. Qual será a sua próxima macro após esta ligação condenseToSingleNSData(id thing)? expandToNSArray(id thing)? Mais cedo ou mais tarde, você perguntará com que classe de classe está lidando, melhor fazê-lo na primeira referência.
Cœur
16

Você deve usar melhor esta categoria:

@implementation NSString (Empty)

    - (BOOL) isWhitespace{
        return ([[self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]length] == 0);
    }

@end
Cœur
fonte
6
Essa definição concluiria que a string "/ r / n / r / n" está vazia, quando claramente não está - ela contém espaço em branco. Sua função é realmente: - (BOOL) isWhitespace (NSString *);
JBRWilkinson
6
Um corolário disso. Eu implementei essa categoria, e há uma torção. Se você chamar isso em uma cadeia nula, essa função nunca será chamada e você receberá um NO (ou o que é avaliado como NO) como um valor de retorno. Então você acha que não está vazio ... Isso pode funcionar se o nome for preenchido ou algo parecido.
Ying
Acho que a categoria correta seria: @implementation NSString (Empty) - (BOOL) empty{ return ([[self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]length] == 0); } @end Como uma combinação da resposta de Marc e Kyle.
palme 25/09
12

Eu coloquei isso:

@implementation NSObject (AdditionalMethod)
-(BOOL) isNotEmpty
{
    return !(self == nil
    || [self isKindOfClass:[NSNull class]]
    || ([self respondsToSelector:@selector(length)]
        && [(NSData *)self length] == 0)
    || ([self respondsToSelector:@selector(count)]
        && [(NSArray *)self count] == 0));

};
@end

O problema é que, se o eu for nulo, essa função nunca será chamada. Retornará false, o que é desejado.

user4951
fonte
melhor solução, já que a) é o método de instância eb) categoria c) nenhum caso em si é manipulado por 'isNotEmpty' Thx!
Denis
Ótima idéia, apenas uma pena -(BOOL)isEmpty{ return ![self isNotEmpty]}não funcionará na categoria.
Alston
Cópia do comentário do @Brane: Se você está em uma situação em que não sabe que tipo de objeto está verificando, acho que isso funciona. No entanto, sugiro que se você não souber se um objeto é NSData ou NSArray, você terá problemas maiores. Qual será a sua próxima macro após esta ligação condenseToSingleNSData(id thing)? expandToNSArray(id thing)? Mais cedo ou mais tarde, você perguntará com que classe de classe está lidando, melhor fazê-lo na primeira referência.
Cœur
11

Outra opção é verificar se ele é igual a @""com isEqualToString:assim:

if ([myString isEqualToString:@""]) {
    NSLog(@"myString IS empty!");
} else {
    NSLog(@"myString IS NOT empty, it is: %@", myString);
}
chown
fonte
11

Apenas passe sua string para o seguinte método:

+(BOOL)isEmpty:(NSString *)str
{
    if(str.length==0 || [str isKindOfClass:[NSNull class]] || [str isEqualToString:@""]||[str  isEqualToString:NULL]||[str isEqualToString:@"(null)"]||str==nil || [str isEqualToString:@"<null>"]){
        return YES;
    }
    return NO;
}
Mani
fonte
Confira os comentários em stackoverflow.com/questions/21605075/… para saber por que isso está errado. Além disso, como isso é melhor do que as outras respostas aqui.
Popeye
6

Basta usar uma das if elsecondições, como mostrado abaixo:

Método 1:

if ([yourString isEqualToString:@""]) {
        // yourString is empty.
    } else {
        // yourString has some text on it.
    }

Método 2:

if ([yourString length] == 0) {
    // Empty yourString
} else {
    // yourString is not empty
}
Samir Jwarchan
fonte
6

Versão rápida

Embora essa seja uma pergunta do Objetivo C, eu precisava usar o NSStringSwift, por isso também incluirei uma resposta aqui.

let myNSString: NSString = ""

if myNSString.length == 0 {
    print("String is empty.")
}

Ou se NSStringfor um opcional:

var myOptionalNSString: NSString? = nil

if myOptionalNSString == nil || myOptionalNSString!.length == 0 {
    print("String is empty.")
}

// or alternatively...
if let myString = myOptionalNSString {
    if myString.length != 0 {
        print("String is not empty.")
    }
}

A Stringversão normal do Swift é

let myString: String = ""

if myString.isEmpty {
    print("String is empty.")
}

Veja também: Verifique a sequência vazia no Swift?

Suragch
fonte
5

Pode ser que essa resposta seja a duplicata das respostas já fornecidas, mas fiz poucas modificações e alterações na ordem de verificação das condições. Consulte o código abaixo:

+(BOOL)isStringEmpty:(NSString *)str
    {
        if(str == nil || [str isKindOfClass:[NSNull class]] || str.length==0) {
            return YES;
       }
        return NO;
    }
iDevAmit
fonte
Esta é uma categoria, você pode ver como criá-la aqui: goo.gl/bRcfn7 . Eu gosto da idéia de uma categoria para este
Daniel Gomez Rico
Não, não podemos dizer que isso é categoria. Se essa função for implementada na categoria da classe NSString, será uma categoria. Caso contrário, podemos chamar esse método com o nome da classe onde quer que o tenhamos implementado. Like Bool isEmptyStr = [MyClassName isStringEmpty: str] Mas ainda assim, será mais bom se o declararmos na categoria. Porque, de alguma forma, também precisamos aproveitar as categorias.
IDevAmit
4

Você pode verificar se sua string está vazia ou não usando este método:

+(BOOL) isEmptyString : (NSString *)string
{
    if([string length] == 0 || [string isKindOfClass:[NSNull class]] || 
       [string isEqualToString:@""]||[string  isEqualToString:NULL]  ||
       string == nil)
     {
        return YES;         //IF String Is An Empty String
     }
    return NO;
}

A melhor prática é fazer com que uma classe compartilhada diga UtilityClass e anuncie esse método para que você possa usar esse método apenas chamando-o através de seu aplicativo.

Fatima Arshad
fonte
4

Você tem 2 métodos para verificar se a sequência está vazia ou não:

Vamos supor que seu nome de string seja NSString *strIsEmpty.

Método 1:

if(strIsEmpty.length==0)
{
    //String is empty
}

else
{
    //String is not empty
}

Método 2:

if([strIsEmpty isEqualToString:@""])
{
    //String is empty
}

else
{
    //String is not empty
}

Escolha qualquer um dos métodos acima e saiba se a string está vazia ou não.

Aditya
fonte
3

Basta verificar o comprimento da corda

 if (!yourString.length)
 {
   //your code  
 }

uma mensagem para NIL retornará nulo ou 0, portanto, não é necessário testar nil :).

Feliz codificação ...

Aks
fonte
Eu usei isso tantas vezes. Absolutamente não há necessidade de extensões, categorias e o que não.
Pnizzle
2

Está funcionando como charme para mim

Se o NSStringés

if ([s isKindOfClass:[NSNull class]] || s == nil || [s isEqualToString:@""]) {

    NSLog(@"s is empty");

} else {

    NSLog(@"s containing %@", s);

}
MaxEcho
fonte
2

Portanto, além do conceito básico de verificar se o comprimento de uma string é menor que 1, é importante considerar o contexto profundamente. Os idiomas humano ou computador ou de outra forma podem ter definições diferentes de cadeias vazias e, nesses mesmos idiomas, um contexto adicional pode alterar ainda mais o significado.

Digamos que string vazia signifique "uma string que não contenha caracteres significativos no contexto atual".

Isso pode significar visualmente, pois na cor e na cor de fundo são as mesmas em uma sequência atribuída. Efetivamente vazio.

Isso pode significar vazio de caracteres significativos. Todos os pontos, traços ou sublinhados podem ser considerados vazios. Além disso, vazio de caracteres significativos significativos pode significar uma sequência que não possui caracteres que o leitor entenda. Eles podem ser caracteres em um idioma ou conjunto de caracteres definido como sem sentido para o leitor. Poderíamos definir um pouco diferente dizer que a string não forma palavras conhecidas em um determinado idioma.

Poderíamos dizer que vazio é uma função da porcentagem de espaço negativo nos glifos renderizados.

Mesmo uma sequência de caracteres não imprimíveis sem representação visual geral não está realmente vazia. Personagens de controle vêm à mente. Especialmente a faixa ASCII baixa (fico surpreso que ninguém tenha mencionado isso porque eles usam muitos sistemas e não são espaços em branco, pois normalmente não têm glifos nem métricas visuais). No entanto, o comprimento da string não é zero.

Conclusão. O comprimento por si só não é a única medida aqui. A associação ao conjunto contextual também é bastante importante.

A associação ao conjunto de caracteres é uma medida adicional comum muito importante. Sequências significativas também são bastante comuns. (pense em SETI ou cripto ou captchas) Também existem conjuntos de contexto mais abstratos.

Portanto, pense com cuidado antes de assumir que uma string está vazia apenas com base no comprimento ou espaço em branco.

uchuugaka
fonte
2

Postagem muito útil, para adicionar suporte ao NSDictionary, bem como uma pequena alteração

static inline BOOL isEmpty(id thing) {
    return thing == nil
    || [thing isKindOfClass:[NSNull class]]
    || ([thing respondsToSelector:@selector(length)]
        && ![thing respondsToSelector:@selector(count)]
        && [(NSData *)thing length] == 0)
    || ([thing respondsToSelector:@selector(count)]
        && [thing count] == 0);
}
Zeev Vax
fonte
Cópia do comentário do @Brane: Se você está em uma situação em que não sabe que tipo de objeto está verificando, acho que isso funciona. No entanto, sugiro que se você não souber se um objeto é NSData ou NSDictionary, você terá problemas maiores. Qual será a sua próxima macro após esta ligação condenseToSingleNSData(id thing)? expandToNSArray(id thing)? Mais cedo ou mais tarde, você perguntará com que classe de classe está lidando, melhor fazê-lo na primeira referência.
Cœur
2
- (BOOL)isEmpty:(NSString *)string{
    if ((NSNull *) string == [NSNull null]) {
        return YES;
    }
    if (string == nil) {
        return YES;
    }
    if ([string length] == 0) {
        return YES;
    }
    if ([[string stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0) {
        return YES;
    }
    if([[string stringByStrippingWhitespace] isEqualToString:@""]){
        return YES;
    }
    return NO;
}
Ptbaileys
fonte
1
Primeiro três condições são redundantes, e você não ter incluído a fonte parastringByStrippingWhitespace
mattsven
2

A melhor maneira é usar a categoria.
Você pode verificar a seguinte função. Que tem todas as condições para verificar.

-(BOOL)isNullString:(NSString *)aStr{
        if([(NSNull *)aStr isKindOfClass:[NSNull class]]){
            return YES;
        }
        if ((NSNull *)aStr  == [NSNull null]) {
            return YES;
        }
        if ([aStr isKindOfClass:[NSNull class]]){
            return YES;
        }
        if(![[aStr stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length]){
            return YES;
        }
        return NO;
    }
Tarun
fonte
1

A melhor maneira, em qualquer caso, é verificar o comprimento da string fornecida. Para isso, se a string for myString, o código será:

    int len = [myString length];
    if(len == 0){
       NSLog(@"String is empty");
    }
    else{
      NSLog(@"String is : %@", myString);
    }
AJS
fonte
1
if (string.length == 0) stringIsEmpty;
InvertedHeli
fonte
1

verifique isto:

if ([yourString isEqualToString:@""])
{
    NsLog(@"Blank String");
}

Ou

if ([yourString length] == 0)
{
    NsLog(@"Blank String");
}

Espero que isso ajude.

Mayur
fonte
1

Você pode facilmente verificar se a string está vazia com isso:

if ([yourstring isEqualToString:@""]) {
    // execute your action here if string is empty
}
user3213914
fonte
1

Eu verifiquei uma string vazia usando o código abaixo:

//Check if we have any search terms in the search dictionary.
if( (strMyString.text==(id) [NSNull null] || [strMyString.text length]==0 
       || strMyString.text isEqual:@"")) {

   [AlertView showAlert:@"Please enter a valid string"];  
}
Jayprakash Dubey
fonte
1

É tão simples quanto if([myString isEqual:@""])ouif([myString isEqualToString:@""])

Ahsan Ebrahim
fonte
1
//Different validations:
 NSString * inputStr = @"Hey ";

//Check length
[inputStr length]

//Coming from server, check if its NSNull
[inputStr isEqual:[NSNull null]] ? nil : inputStr

//For validation in allowed character set
-(BOOL)validateString:(NSString*)inputStr
{
    BOOL isValid = NO;
    if(!([inputStr length]>0))
    {
        return isValid;

    }

    NSMutableCharacterSet *allowedSet = [NSMutableCharacterSet characterSetWithCharactersInString:@".-"];
    [allowedSet formUnionWithCharacterSet:[NSCharacterSet decimalDigitCharacterSet]];
    if ([inputStr rangeOfCharacterFromSet:[allowedSet invertedSet]].location == NSNotFound)
    {
        // contains only decimal set and '-' and '.'

    }
    else
    {
        // invalid
        isValid = NO;

    }
    return isValid;
}
Rohit Kashyap
fonte
0

Você pode ter uma sequência vazia de duas maneiras:

1) @ "" // Não contém espaço

2) @ "" // Contém espaço

Tecnicamente, as duas cordas estão vazias. Podemos escrever as duas coisas apenas usando UMA condição

if ([firstNameTF.text stringByReplacingOccurrencesOfString:@" " withString:@""].length==0)
{
    NSLog(@"Empty String");
}
else
{
    NSLog(@"String contains some value");
}
Chetan Rajauria
fonte
0

Tente o seguinte

NSString *stringToCheck = @"";

if ([stringToCheck isEqualToString:@""])
{
   NSLog(@"String Empty");
}
else
{
   NSLog(@"String Not Empty");
}
Rich Allen
fonte
-1
if(str.length == 0 || [str isKindOfClass: [NSNull class]]){
    NSLog(@"String is empty");
}
else{
    NSLog(@"String is not empty");
}    
C_compnay
fonte
1
A verificação nula deve ser a primeira. str.lengthlançará uma exceção se strfor nulo.
Jeffery Thomas
-2
if( [txtMobile.text length] == 0 )
{
    [Utility showAlertWithTitleAndMessage: AMLocalizedString(@"Invalid Mobile No",nil) message: AMLocalizedString(@"Enter valid Mobile Number",nil)];
}
Mohsin Sabasara
fonte