¿Cuál es la forma correcta de comprobar si hay una cadena nula en Objective-C?


Estaba usando esto en mi aplicación para iPhone

if (title == nil) {
    // do something
}

Pero lanza alguna excepción, y la consola muestra que el título es "(null)".

Así que estoy usando esto ahora:

if (title == nil || [title isKindOfClass:[NSNull class]]) {
    //do something
}

¿Cuál es la diferencia y cuál es la mejor manera de determinar si una cadena es nula?

Author: Ashwini, 2009-06-09

18 answers

Como otros han señalado, hay muchos tipos de "null" bajo Cocoa/Objective C. Pero una cosa más a tener en cuenta es que [title isKindOfClass:[NSNull class]] es innecesariamente complejo ya que [NSNull null] está documentado como un singleton por lo que solo puede comprobar la igualdad de puntero. Ver Temas para Cocoa: Usando Null.

Así que una buena prueba podría ser:

if (title == (id)[NSNull null] || title.length == 0 ) title = @"Something";

Tenga en cuenta cómo se puede utilizar el hecho de que incluso si el título es nil, título.length devolverá 0 / nil / false, es decir, 0 en este caso, así que usted no tiene que caso especial. Esto es algo a lo que las personas que son nuevas en Objective C tienen problemas para acostumbrarse, especialmente viniendo de otros lenguajes donde los mensajes/llamadas de método a nil se bloquean.

 375
Author: Peter N Lewis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-05 03:14:01

Es tan simple como

if([object length] >0)
{
  // do something
}

Recuerde que en objective C si object es null devuelve 0 como valor.

Esto le dará una cadena nula y una cadena de longitud 0.

 24
Author: Bluephlame,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-21 08:23:04

Consulte los siguientes artículos relacionados en este sitio:

Creo que su error está relacionado con algo más, ya que no debería tener que hacer la comprobación adicional.

También vea esta pregunta relacionada: Comprobación adecuada de la columna de texto nil sqlite

 6
Author: TimM,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:15

¿Qué pasa con todas estas respuestas de "works for me"? Todos estamos codificando en el mismo idioma y las reglas son

  1. Asegúrese de que la referencia no es nil
  2. Compruebe y asegúrese de que la longitud de la cadena no es 0

Eso es lo que funcionará para todos. Si una solución dada solo "funciona para usted", es solo porque su flujo de aplicación no permitirá un escenario donde la referencia puede ser nula o la longitud de la cadena a ser 0. La forma correcta de hacer esto es el método que maneja lo que quieras en todos los casos.

 5
Author: nenchev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-11 14:01:51

He encontrado que para realmente hacerlo bien terminas teniendo que hacer algo similar a

if ( ( ![myString isEqual:[NSNull null]] ) && ( [myString length] != 0 ) ) {
}

De lo contrario, obtendrás situaciones extrañas en las que el control seguirá eludiendo tu cheque. No me he encontrado con uno que lo hace más allá de los controles isEqual y longitud.

 5
Author: Guardius,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-30 18:45:16

Si desea probar con todos los objetos nil / empty (como cadenas vacías o arrays/conjuntos vacíos) puede usar lo siguiente:

static inline BOOL IsEmpty(id object) {
    return object == nil
        || ([object respondsToSelector:@selector(length)]
        && [(NSData *) object length] == 0)
        || ([object respondsToSelector:@selector(count)]
        && [(NSArray *) object count] == 0);
}
 4
Author: diederikh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-09 10:55:07

Hay dos situaciones:

Es posible que un objeto sea [NSNull null], o es imposible.
Su aplicación generalmente no debería usar [NSNull null]; solo lo usa si desea poner un objeto " null" en una matriz, o usarlo como un valor de diccionario. Y entonces usted debe saber qué matrices o diccionarios podrían contener valores nulos, y que podría no.
Si crees que un array nunca contiene valores [NSNull null], entonces no lo compruebes. Si hay un [NSNull null], puede obtener una excepción, pero eso está bien: las excepciones de Objective-C indican errores de programación. Y tienes un error de programación que necesita arreglarse cambiando algún código.

Si un objeto podría ser [NSNull null], entonces comprueba esto simplemente probando
(object == [NSNull null]). Llamar a isEqual o comprobar la clase del objeto no tiene sentido. Solo hay un objeto [NSNull null], y el viejo operador C lo comprueba bien de la manera más directa y eficiente.

Si comprueba un objeto NSString que no puede ser [NSNull null] (porque sabes que no puede ser [NSNull null] o porque acabas de comprobar que es diferente de [NSNull null], entonces necesitas preguntarte cómo quieres tratar una cadena vacía, que es una con longitud 0. Si se trata de una cadena null como nil, entonces pruebe (object.length == 0). objeto.length devolverá 0 if object == nil, por lo que esta prueba cubre objetos nil y cadenas con longitud 0. Si tratas una cadena de longitud 0 diferente de una cadena nil, simplemente comprueba si object == nil.

Finalmente, si desea agregar una cadena a un array o diccionario, y la cadena podría ser nil, tiene la opción de no agregarla, reemplazarla con @"" o reemplazarla con [NSNull null]. Reemplazarlo con @"" significa que pierde la capacidad de distinguir entre "sin cadena" y "cadena de longitud 0". Reemplazarlo con [NSNull null] significa que tiene que escribir código cuando accede a la matriz o diccionario que comprueba los objetos [NSNull null].

 3
Author: gnasher729,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-30 18:49:52

Usted acaba de comprobar para nada

if(data[@"Bonds"]==nil){
  NSLog(@"it is nil");
}

O

if ([data[@"Bonds"] isKindOfClass:[NSNull class]]) {
    NSLog(@"it is null");
}
 2
Author: Gami Nilesh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-13 01:49:58
if(textfield.text.length == 0){
   //do your desired work
}
 1
Author: Muhammad Aamir Ali,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-15 17:48:19

Pruebe esto para comprobar null

 if (text == nil)
 1
Author: Vineesh TP,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-01 09:58:31
@interface NSString (StringFunctions)
- (BOOL) hasCharacters;
@end

@implementation NSString (StringFunctions)
- (BOOL) hasCharacters {
    if(self == (id)[NSNull null]) {
        return NO;
    }else {
        if([self length] == 0) {
            return NO;
        }
    }
    return YES;
}
@end

NSString *strOne = nil;
if([strOne hasCharacters]) {
    NSLog(@"%@",strOne);
}else {
    NSLog(@"String is Empty");
}

Esto funciona con los siguientes casos, NSString *strOne = @"" O NSString *strOne = @"StackOverflow" O NSString *strOne = [NSNull null] O NSString *strOne.

 1
Author: Hemang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-07 04:52:09

Aquí está la macro que uso para cadena segura en lugar de obtener cadena" (null) " en una etiqueta UILabel, por ejemplo:

#define SafeString(STRING) ([STRING length] == 0 ? @"" : STRING)

Digamos que tienes una propiedad member class y name, y name es nil:

NSLog(@"%@", member.name); // prints (null) on UILabel

Con macro:

NSLog(@"%@", SafeString(member.name)); // prints empty string on UILabel

Agradable y limpio.

 1
Author: mgyky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-25 06:19:24

Si ese tipo de cosas no existe ya, puedes crear una categoría NSString:

@interface NSString (TrucBiduleChoseAdditions)

- (BOOL)isEmpty;

@end

@implementation NSString (TrucBiduleChoseAdditions)

- (BOOL)isEmpty {
    return self == nil || [@"" isEqualToString:self];
}

@end
 0
Author: Rémy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-09 08:25:24

Lo que funciona para mí es if ( !myobject )

 0
Author: Joseph Bolade Caxton-Idowu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-18 01:19:28

La comprobación completa de una cadena para condiciones nulas puede ser la siguiente:

    if(mystring)
     {
       if([mystring isEqualToString:@""])
        {
          mystring=@"some string";
        }
     }    
    else
     {
        //statements
     }
 0
Author: Alen Alexander,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-11 07:15:06

Solo compruebo la cadena nula con

If ([myString isEqual: [NSNull null]])

 0
Author: JerryZhou,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-28 07:30:51
if ([linkedStr isEqual:(id)[NSNull null]])
                {
                    _linkedinLbl.text=@"No";
                }else{
                    _linkedinLbl.text=@"Yes";
                }
 -1
Author: SWAMY CHUNCHU,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-06 11:03:07
if ([strpass isEqual:[NSNull null]] || strpass==nil || [strpass isEqualToString:@"<null>"] || [strpass isEqualToString:@"(null)"] || strpass.length==0 || [strpass isEqualToString:@""])
{
    //string is blank  
}
 -1
Author: saurabh rathod,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-18 09:02:20