¿Objective-C usa la evaluación de cortocircuito?

Intenté algo como:

if(myString != nil && myString.length) { ... } 

Y consiguió:

– [NSNull length]: selector no reconocido enviado a la instancia

¿Objetive-C no produce un cortocircuito después de que falla la primera condición?

Objective-C no admite la evaluación de cortocircuito, al igual que C.

Parece que en tu ejemplo myString es NSNull y no es nil , por myString != nil tanto myString != nil es verdadero.

NSNull es un singleton y se usa para representar nil donde solo se permiten objetos, por ejemplo en un NSArray.

Por cierto, normalmente, las personas escriben if (!myString && myString.length == 0) . Comparar con nil es bastante feo. Además, compararía la longitud con 0. Eso parece ser más claro.

Objective-C es un superconjunto estricto de C.

Como C admite la evaluación de cortocircuito, Objective-C también lo hace.

¿Qué es NSNull definido como? Si se trata de un objeto que se supone que no representa nada, entonces no sería nulo. en otras palabras, NSNull y nil no son lo mismo.

Si tiene un NSNull en alguna parte, probablemente esté usando un analizador JSON o CoreData. Cuando un número en CoreData no está configurado, CoreData le devolverá NSNull; posiblemente lo mismo ocurra con los valores de NSString en CoreData.

De manera similar, puede tener elementos vacíos en JSON devueltos desde un servidor y algunos analizadores le darán eso como un objeto NSNull. Por lo tanto, en ambos casos, debe tener cuidado cuando use valores, ya que lo que usted pensó que era un objeto NSSumerg o NSNumber es realmente NSNull.

Una solución es definir una categoría en NSNull que simplemente ignora todos los mensajes no comprendidos que se envían al objeto, según el código siguiente. Entonces el código que tiene funcionaría porque NSNull.length devolvería 0. Puede incluir algo como esto en su archivo de proyecto .pch, que se incluye en cada archivo de su proyecto.

 // NSNull+IgnoreMessages.h @interface NSNull(IgnoreMessages) - (void)forwardInvocation:(NSInvocation *)anInvocation; - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector; @end //NSNull+IgnoreMessages.m #import "NSNull+IgnoreMessages.h" @implementation NSNull(IgnoreMessages) - (void)forwardInvocation:(NSInvocation *)anInvocation { if ( [self respondsToSelector:[anInvocation selector]] ) [anInvocation invokeWithTarget:self]; } - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector { NSMethodSignature *sig=[[NSNull class] instanceMethodSignatureForSelector:aSelector]; // Just return some meaningless signature if(sig==nil) sig=[NSMethodSignature signatureWithObjCTypes:"@^v^c"]; return sig; } @end