Soru Amaç-C kısa devre değerlendirmesini kullanıyor mu?


Çizgiler boyunca bir şey denedim:

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

Ve var:

- [NSNull length]: örneğe gönderilen tanınmayan seçici

İlk koşuldan sonra Objektif-C kısa devre yapmıyor mu?


18
2018-01-13 22:23


Menşei


mı NSNull eşittir nil? - Anon.
Hayır! NSNull ve nil aynı şey değildir. Bir şey değil. - bbum


Cevaplar:


Objective-C, C gibi kısa devre değerlendirmesini destekliyor.

Örnekte öyle görünüyor ki myString olduğu NSNull ve yok nilbu nedenle myString != nil doğru.

NSNull bir singleton ve temsil etmek için kullanılır nil sadece bir nesneye izin verilir, örneğin bir NSArray içinde.

Btw, normalde insanlar yazıyor if (!myString && myString.length == 0). İle karşılaştırılıyor nil oldukça çirkin. Ayrıca, uzunluğu 0 ile karşılaştırırım. Bu daha net görünüyor.


30
2018-01-13 22:28



Bahşiş için teşekkürler. Ben hala tüm sözdizimi ve adlandırma kuralları ile kendimi hizalamaya çalışıyorum. - kwcto
İnsanların normalde 'nil ile kıyaslamadığını söyleyemem. Eşit frekansta iki yolla yapıldığını gördüm. Tartışma, 'myString olmasa da' myString değilse 'olarak okuyabiliyor olmanızdır. - bobDevil
Aslında nil ile karşılaştırmak yanlış (nil == variable) bir mesajın bir nil nesnesine gönderilmediğinden emin olmanın doğru yoludur. - Matt Hudson
@Inturbidus: Ne demek istediğini anladığımdan emin değilim. Eğer birinin kullanması gerektiğini düşünüyorsanız if (nil == myString) yerine if (!myString) yanılıyorsun. nil 0 olarak tanımlanır ve bu nedenle iki karşılaştırma tam olarak aynıdır. - Georg Schölly
Teknik olarak, sadece yapabilirsin if(myString.length) {...} ve eğer bunu bıraksam, çünkü eğer myString bir nil nesnesi ise ve ona bir uzunluk mesajı gönderirseniz, yine de nil olacaktır. - Matt Mc


Amaç-C, C'nin sıkı bir üst kümesidir.

C kısa devre değerlendirmesini desteklediğinden, Objective-C de bunu yapar.


10
2018-01-13 22:28



NString * str = ifadeThatReturnsStrOrNil () || @ ""; çalışmıyor. Bu kısa devre değerlendirmesi çalışmıyor. - Pedro Morte Rolo
@PedroMorteRolo: Tabii ki çalışıyor. Ne sonuç bekliyorsun? (Bunun ||operatör ya 1 veya 0, asla başka bir şey). - Stephen Canon
Haklısın. C'nin Ruby ile aynı semantiğe sahip olduğu yanılsamasına düştüm. - Pedro Morte Rolo


NSNull nedir? Hiçbir şeyi temsil etmemesi gereken bir nesne ise, sıfır olmayacaktır. Başka bir deyişle, NSNull ve nil aynı değildir.


3
2018-01-13 22:28





Bir yerlerde NSNull varsa, muhtemelen bir JSON ayrıştırıcısı veya CoreData kullanıyorsunuzdur. CoreData'da bir sayı ayarlanmadığında, CoreData NSNull'u geri verir - muhtemelen CoreData'daki NSString değerleri için de aynıdır.

Benzer şekilde, JSON'da bir sunucudan döndürülen boş öğeleriniz olabilir ve bazı ayrıştırıcılar size bir NSNull nesnesi olarak verir. Yani her iki durumda da, bir NSString veya NSNumber nesnesi olduğunu düşündüğünüz şey gerçekten NSNull olduğundan değerleri kullanırken dikkatli olmalısınız.

Bir çözüm, NSNull'da, aşağıdaki kod uyarınca, nesneye gönderilen tüm anlaşılmamış mesajları basitçe yok sayan bir kategori tanımlamaktır. Daha sonra, NSNull.length 0 döndüreceği için sahip olduğunuz kod işe yarar. Projenizdeki her bir dosyaya dahil olan proje .pch dosyasında buna benzer bir şey ekleyebilirsiniz.

// 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

0
2018-01-14 01:01



Bu sadece başarısız olmayı bekliyor. Ne zaman uğraştığınızı bilmek önemlidir NSNull yerine nil, kodunuz daha az gerçekleşmesini sağlıyor. Sorunun örneğinde, aşağıdakileri içeren bir hata mesajı var NSNullBunu kodunuzla göremezsiniz. if (myString) hala doğruyu değerlendirirdi. - Georg Schölly
Öyleyse, bana nil gibi herhangi bir mesaj gönderirseniz nasıl başarısız olabileceğini söyleyin ... ve hala NSNull (tüm NSObject yöntemleri dahil) tarafından gerçekten anlaşılan herhangi bir mesaja bağlanacaktır. Şimdi, hataya neden olabilir, çünkü doğru olmayacaksa, nil ile eşdeğerlik için açıkça kontrol edersiniz. Ama çoğu kodlamada, tam olarak nil herhangi bir mesaj gönderilebileceğinden, sadece burada iyi çalışan (myString.length> 0) gibi bir şeye karşı test ediyorum. Gerçekten de, bu kod, bir NSNull beklemediğiniz yerde kayarken kodunuzda olası çökmeleri ÖNLEMEK, böylece denge üzerinde bir denge kazancıdır. - Kendall Helmstetter Gelner
Ayrıca, nerede bir hata mesajı yazıyor? Bu hiç bir anlam ifade etmiyor, neden NSNull'ı bir NSString'in yerine gönderen bir hata mesajı göndermek istesin? Pratikte, sadece NSNull'un CoreData'dan ve bazı JSON Parsers'tan çıktığını, bu testin bariz olmayan çalışma zamanı hatalarını engellemenin dışında hiçbir şey yapmadığı bir şekilde görmüştüm. Hala önemli olan NSNull'u kontrol edebilirsiniz. - Kendall Helmstetter Gelner
Hata mesajında ​​şu soruya değinilmektedir: - [NSNull length]: örneğe gönderilen tanınmayan seçici. Tekniğin çökmeleri önlediğini söylemek son derece tehlikeli. Bu çökmeler sadece programcı olduğu için var olacaktı NSNull'un geri döndüğünü görmedim. Bu, maskeleme hatalarının mükemmel bir örneğidir. Ve bu durumda, eğer bir şeyle bir şeyler yapıyorsa, veri kaybına yol açabilir. NSNull. - Georg Schölly
neden sadece değil NSMethodSignature *sig=[self methodSignatureForSelector:aSelector]; - user102008