Я попробовал что-то вроде:
if(myString != nil && myString.length) { ... }
И добрался:
- [Длина NSNull]: непризнанный отборщик послал в случай
Разве Цель-C не срывает после того, как первое условие терпит неудачу?
Objective-C действительно поддерживает оценку короткого замыкания, так же как и C.
Кажется, что в Вашем примере myString
- это NSNull
, а не nil
, поэтому myString != nil
- это правда.
NSNull является однотонным и используется для представления nil
, где разрешены только объекты, например, в NSArray.
Btw, обычно, люди пишут если (!myString && myString.length == 0)
. Сравнение с nil
довольно уродливо. Также я бы сравнил длину с 0. Это кажется более понятным.
Objective-C представляет собой строгий суперсетом C.
, потому что C поддерживает оценку короткого замыкания, и объективно-C делает также.
Что такое NSNULL как? Если это объект, который предполагается представлять ничего, чем не будет ноль. Другими словами, Nsnull и Nil не одинаковы.
Если у вас где-то есть NSNull, вы, вероятно, используете JSON парсер или CoreData. Когда число в CoreData не установлено, CoreData вернет вам NSNull - возможно, то же самое относится и к значениям NSString в CoreData.
Аналогично, вы можете получить пустые элементы в JSON, возвращенные с сервера, и некоторые парсеры вернут их вам в качестве объекта NSNull. Так что в обоих случаях, вы должны быть осторожны, когда используете значения, так как вещь, которую вы считали объектом NSString или NSNumber, на самом деле является NSNull.
Одним из решений является определение категории на NSNull, которая просто игнорирует все непонятные сообщения, посылаемые объекту, как показано в коде ниже. Тогда код, который у вас есть, будет работать, потому что NSNull.length вернет 0. Вы можете включить что-нибудь подобное в ваш проектный .pch файл, который включается в каждый отдельный файл вашего проекта.
// 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