Objective-C'de boş bir dize olup olmadığını denetlemenin doğru yolu nedir?


184

Bunu iPhone uygulamamda kullanıyordum

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

ancak bir istisna oluşturur ve konsol başlığın "(null)" olduğunu gösterir.

Şimdi bunu kullanıyorum:

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

Fark nedir ve bir dizenin boş olup olmadığını belirlemenin en iyi yolu nedir?


Yanıtlar:


395

Diğerlerinin de işaret ettiği gibi, Kakao / Amaç C altında birçok çeşit "null" vardır. Ancak dikkat edilmesi gereken bir diğer şey, [title isKindOfClass: [NSNull class]] 'ın [NSNull null] bir sadece işaretçi eşitliğini kontrol edebilirsiniz. Bkz . Kakao Konuları: Null Kullanımı .

Yani iyi bir test olabilir:

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

Başlık nil olsa bile, title.length öğesinin 0 / nil / false, yani bu durumda 0 döndüreceği gerçeğini nasıl kullanabileceğinizi unutmayın, bu nedenle özel bir duruma gerek yoktur. Bu, Objective C'de yeni olan kişilerin, özellikle mesajların / yöntemin nil kazaya çağırdığı diğer dillerden gelmekte zorlandığı bir şeydir.


Teşekkürler! Ancak ilk etapta bu soruyu sordum çünkü "başlık" boş olduğu için istisna alıyordum
Teo Choong Ping

1
Başlık ne tür olmalı? Örneğin, bir NSString ise, aşağıdaki uyarıyı alırım: farklı Objective-C türlerinin karşılaştırması 'struct NSNull *' ve 'struct NSString *' kadrodan yoksundur Bunu kaldırmanın herhangi bir yolu var mı bu soru soruldu)?
thebossman

1
;-) derlemeden kod yayınlama hakkım var. başlık büyük olasılıkla bir NSString'tir, ancak başlığın türüne bakılmaksızın, yalnızca genel id türüne null değerini verir: (id) [NSNull null].
Peter N Lewis

1
@JLT nil ve [NSNull null] asla aynı olmaz. [NSNull null], nil kullanılamadığında (örneğin, bir NSArray veya NSDictionary değerinde) sıfır için bir stand olarak kullanılabilen tekli bir nesnedir. Bu nedenle, bazıları null olabilecek isteğe bağlı dizelerin bir NSArray'ına sahip olduğunuz ve null durumlarda dizide [NSNull null] kullandığınız bir kullanım durumu olabilir. Uygulamada, teste nadiren ihtiyaç vardır, ancak siz (veya kullandığınız bir kütüphane!) Yer tutucu olarak aktif olarak [NSNull null] kullandığınızda.
Peter N Lewis

1
Flutter adlı Buraya gelmek ve neden sebep arıyor Mapmaddenin değeri - olduğu nullDart içinde - uyuşmuyor nilveya NULLnedeni aslında olmasıydı Amaç C. NUNull nulldeğil NULLboş. Teşekkürler @PeterNLewis!
Aleksandar

25

o kadar basit

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

Hedef C'de nesne null olursa, değer olarak 0 döndürdüğünü unutmayın.

Bu size hem boş bir dize hem de 0 uzunlukta bir dize getirecektir.


49
Nesne NSNull ise bu çalışmaz, yine de öncelikle bunu açıkça kontrol etmeniz gerekir.
Jeremy Mack

6
Ayrıca NSNull için uzunluk iletisine 0 döndürmesi için bir kategori de oluşturabilirsiniz :)
Mihai Timar

1
Evet, nesne NSNull ise çökecektir.
Mike Gledhill

Nesne NSNull'a eşitse çökecektir
joan

1
NSNull tanınmayan seçici sorununa ek olarak, bu nil olan bir NSString işaretçisi veya aslında orada olan ancak aslında boş bir dize olan bir NSString arasında ayrım yapmaz. (Örneğin değişmez olarak object = @"";veya object = nil;)
KellyTheDude

6

Bu sitede aşağıdaki ilgili makalelere bakın:

Ek kontrolü yapmanıza gerek olmaması gerektiği için hatanızın başka bir şeyle ilgili olduğunu düşünüyorum.

Ayrıca bu ilgili soruya bakın: Nil sqlite metin sütununun doğru kontrolü


Can sıkıcı bir şekilde (bu sitede bir şey için bile) ikinci bir köprü eklemek için yeterli "puan" yok ayrıca bkz: - stackoverflow.com/questions/598396/…
TimM

...bana izin ver. Her ne kadar rep 0'dan kendi yazılarınızı düzenleyebilmelisiniz
Rog

Teşekkürler - bu çok nazikti. İlk yazımı yazdığımda, yeni kullanıcılar gibi sadece bir şey ekleyebileceğini söyledi (bu biraz sert görünüyor - özellikle bu sitedeki çapraz bağlantılar için).
TimM

6

Gerçekten doğru yapabilmek için, benzer bir şey yapmak zorunda kaldığını buldum.

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

Aksi takdirde, kontrolün yine de kontrolünüzü atlayacağı garip durumlar elde edersiniz. Ben onu geçmiş bir tane ile karşılaşmadımisEqual ve uzunluk kontrolleri.


5

Tüm bu "benim için çalışıyor cevapları" ne? Hepimiz aynı dilde kod yazıyoruz ve kurallar

  1. Referansın sıfır olmadığından emin olun
  2. Dizenin uzunluğunun 0 olmadığından emin olun ve emin olun

Herkes için işe yarayacak olan budur. Belirli bir çözüm yalnızca "sizin için çalışıyorsa", bunun nedeni yalnızca uygulama akışınızın başvurunun boş olabileceği veya dize uzunluğunun 0 olabileceği bir senaryoya izin vermemesidir. Bunu yapmanın uygun yolu, her durumda ne istediğinizi.


4
Başvuru nil(not: "null" değil) ise, gibi bir mesaj göndermek length0 (veya yöntemin dönüş türü için uygun 0 değeri) üretir. Dilin kuralı budur . nilBu durumda ayrı ayrı kontrol etmeye gerek yoktur .
jscs

Ben sadece C ++ alışkanlıkları nedeniyle null dedim ve kod nil nesneler üzerinde yöntemler çağırıyorsa, şans kodunuzu kırık vardır. NULL / NIL (aynı kavram) üzerinde arama yöntemlerinin herhangi bir dilde genellikle kötü bir fikir olduğunu göreceksiniz. Obj-c'nin böyle bir şey yapmanıza izin vermesi, nil nesnelerin etrafından geçmeniz ve onları umursamadan kullanmaya çalışmanız gerektiği anlamına gelmez.
nenchev

1
Nil'e uzunluk göndermek 0 üretir, ancak NSNull'a gönderme uzunluğu bir istisna oluşturur.
cdstamper

@nenchev Kimse sadece nil nesnelerinin etrafından geçme hakkında bir şey söylemez, ancak nil'i kontrol etmek, sonra bir yöntemi çağırmak ve dönüş değerini kullanmak, IMO'nun kullanılması ve daha sonra yöntemin dönüş değerinin geçerliliğini kontrol etmesi gibi bir dil özelliğini kullanmaktan daha kötü değildir.
Kevin

@Kevin bunun nasıl daha kötü olduğundan emin değilim, çünkü bir dil özelliği harika olduğu anlamına gelmiyor. Null değerinin, çalışma zamanı hatasını izlemenin daha zor olmasına neden olabilecek bir kod yolu açıp açamayacağını denetlememek. Girdilerinizin beklediğiniz gibi olduğunu doğrulamak ve uygun değilse tepki vermek genellikle en iyisidir. Ben kişisel olarak bir nil nesnesine bir mesaj göndermeye çalışırken çalışma zamanı istisnaları almamanın "özelliği" sevmiyorum, çünkü genellikle bazı çalışma zamanı hataları kaçırmak kolaylaştırır.
nenchev

4

Tüm sıfır / boş nesnelere (boş dizeler veya boş diziler / kümeler gibi) karşı sınamak istiyorsanız aşağıdakileri kullanabilirsiniz:

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);
}

2
Bu, aslında mantıklı olan == [NSNull null] nesnesini kontrol etmez.
Peter N Lewis

3

İki durum vardır:

Bir cismin olması [NSNull null]veya imkansız olması mümkündür .
Uygulamanız genellikle [NSNull null];onu yalnızca bir diziye " null " nesne koymak veya sözlük değeri olarak kullanmak istiyorsanız kullanmamalıdır. Ve sonra hangi dizilerin veya sözlüklerin boş değerler içerebileceğini ve hangilerinin bulunmayabileceğini bilmelisiniz.
Bir dizinin asla [NSNull null]değer içermediğini düşünüyorsanız, diziyi kontrol etmeyin. Bir varsa, bir [NSNull null]istisna alabilirsiniz, ancak sorun değil: Objective-C istisnaları programlama hatalarını gösterir. Bazı kodları değiştirerek düzeltilmesi gereken bir programlama hatası var.

Bir nesne ise olabilirdi olmak [NSNull null], o zaman test ederek oldukça basit bu kontrol
(object == [NSNull null]). isEqualNesnenin sınıfını çağırmak veya kontrol etmek saçmadır. Sadece bir [NSNull null]nesne vardır ve sade eski C operatörü en basit ve en verimli şekilde iyi olup olmadığını kontrol eder.

Olamayacak bir NSStringnesneyi kontrol ederseniz [NSNull null]( olamayacağını bildiğiniz için [NSNull null]veya sadece farklı olduğunu kontrol ettiğiniz için), [NSNull null]kendinize boş bir dizeyi nasıl tedavi etmek istediğinizi sormanız gerekir, bu uzunluk 0'dır. Bunun nullgibi bir dize gibi davranın nil, sonra test (object.length == 0). object.length 0 döndürürse object == nil, bu test 0 nil nesnelerini ve 0 dizesini kapsar. 0 nil uzunluğundaki bir dizeyi nil dizgiden farklı bir şekilde ele alırsanız, sadece kontrol edin object == nil.

Son olarak, bir diziye veya sözlüğe bir dize eklemek istiyorsanız ve dize nil olabilirse, diziyi eklememe, onunla değiştirme @""veya onunla değiştirme seçeneğiniz vardır [NSNull null]. @""Onun yerine "dizgi yok" ve "uzunluk dizesi 0" arasında ayrım yapma olanağını kaybedersiniz. Bunu değiştirmek [NSNull null], [NSNull null]nesneleri kontrol eden diziye veya sözlüğe eriştiğinizde kod yazmanız gerektiği anlamına gelir .


Çok uzun, ama bu iyi. NSNull SADECE TEKLİFLERDE GÖRÜNMELİDİR! Tüm bu soru bir anlam ifade etmiyor, kodlayıcının doğru bir şey yapmadığını söylüyor ve gelecekte daha birçokları manuel / iyi kod uygulamasını okumadı
Stephen J

2

Sadece nil'i kontrol et

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

veya

if ([data[@"Bonds"] isKindOfClass:[NSNull class]]) {
    NSLog(@"it is null");
}

2

MAKRO Çözümü (2020)

İşte bir UILabel örneğin " (null) " dizesi yerine güvenli dize için kullandığım makro :

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

üye sınıfınız ve name özelliğiniz olduğunu ve name nil olduğunu varsayalım:

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

makro ile:

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

nice and clean 😊 Instagram Hesabında Takip Ettikleri

Genişletme Çözümü (2020)

Projenizde nil Null ve boş dizeyi kontrol etmeyi tercih ediyorsanız, aşağıdaki uzantı satırımı kullanabilirsiniz:

NSString + Extension.h

///
/// Checks if giving String is an empty string or a nil object or a Null.
/// @param string string value to check.
///
+ (BOOL)isNullOrEmpty:(NSString*)string;

NSString + Extension.m

+ (BOOL)isNullOrEmpty:(NSString*)string {
    if (string) { // is not Nil
        NSRange range = [string rangeOfString:string];
        BOOL isEmpty = (range.length <= 0 || [string isEqualToString:@" "]);
        BOOL isNull = string == (id)[NSNull null];

        return (isNull || isEmpty);
    }

    return YES;
}

Örnek Kullanım

if (![NSString isNullOrEmpty:someTitle]) {
    // You can safely use on a Label or even add in an Array for example. Remember: Arrays don't like the nil values!
}



1
@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");
}

Bu, aşağıdaki durumlarda NSString *strOne = @""VEYA NSString *strOne = @"StackOverflow"VEYA NSString *strOne = [NSNull null]VEYA NSString *strOne.


0

Bu tür bir şey yoksa, bir NSString kategorisi yapabilirsiniz:

@interface NSString (TrucBiduleChoseAdditions)

- (BOOL)isEmpty;

@end

@implementation NSString (TrucBiduleChoseAdditions)

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

@end

Muhtemelen aşırıya kaçmış ve bu sorunu çözeceğini düşünmüyorum.
Rog

9
Benlik == nil anlamsızdır - benlik sıfır olsaydı, Objective C sizi en başta çağırmazdı. [(NSString *) nil isEmpty] kodunuzu çağırmadan 0 / nil / false döndürür.
Peter N Lewis

4
Aslında bunun ötesinde, [(NSString *) nil isEmpty] yanlış döndürür. Bu tür Objective C yöntemleri yazarken, nil 0 / nil / false mantıklı olacak şekilde tanımlamak daha iyidir, bu nedenle yöntemi hasCharacters olarak yazmak daha iyi olur. Eğer uzunluk (! S.isEmpty) ve s.length, s == nil durumunda 0 değerini döndürürse kullanabilirsiniz.
Peter N Lewis

Bu ciddi bir kaza. NSString için "isEmpty" uyguladınız, ancak aslında NSNull ise, o zaman NSEull'e isEmpty gönderilecek ve bu iletiye yanıt vermediğinden çökecektir!
daniel.gindi

0

Benim için işe yarayan şey if ( !myobject )


3
Bu null nesneler için değil, sadece nil nesneler için işe yarar. Örneğin ... NSArray *testarray = [NSArray arrayWithObjects:[NSNull null],@"", nil]; NSString *string = [testarray objectAtIndex:0]; NSLog(@"null string value: %@",string); if (!string) { NSLog(@"string evaluates to null"); } if (string && (string==(id)[NSNull null])) { NSLog(@"string does not evaluate to null"); }
Rik Smith-Unna

Hata .. biçimlendirme için üzgünüm, ama kod derleyecek :)
Rik Smith-Unna

0

Bir dizenin boş koşullar için tam denetimi aşağıdaki gibi olabilir: <\ br>

    Eğer (MyString)
     {
       if ([gizem isEqualToString: @ ""])
        {
          mystring = @ "bazı dizeler";
        }
     }    
    Başka
     {
        // ifadeleri
     }

0

Yalnızca boş dizeyi

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


0
if ([linkedStr isEqual:(id)[NSNull null]])
                {
                    _linkedinLbl.text=@"No";
                }else{
                    _linkedinLbl.text=@"Yes";
                }

1
Bu kod snippet'i soruyu cevaplayabilirken, nasıl veya nedenini açıklayan herhangi bir bağlam sağlamaz. Cevabınızı açıklamak için bir veya iki cümle eklemeyi düşünün.
brandonscript

0
if ([strpass isEqual:[NSNull null]] || strpass==nil || [strpass isEqualToString:@"<null>"] || [strpass isEqualToString:@"(null)"] || strpass.length==0 || [strpass isEqualToString:@""])
{
    //string is blank  
}

0

Dize için:

+ (BOOL) checkStringIsNotEmpty:(NSString*)string {
if (string == nil || string.length == 0) return NO;
return YES;

}

Aşağıdaki resme bakın:

resim açıklamasını buraya girin


0

Dize için:

+ (BOOL) checkStringIsNotEmpty:(NSString*)string {
if (string == nil || string.length == 0) return NO;
return YES;}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.