Objective-Cでnull文字列をチェックする正しい方法は何ですか?


184

iPhoneアプリでこれを使用していた

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

しかし、それはいくつかの例外をスローし、コンソールはタイトルが "(null)"であることを示します。

だから私は今これを使っています:

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

違いは何ですか?また、文字列がnullかどうかを判断する最良の方法は何ですか?


回答:


395

他の人が指摘したように、Cocoa / Objective Cの下には多くの種類の「null」があります。ただし、[title isKindOfClass:[NSNull class]]は、[NSNull null]がシングルトンなので、ポインタが等しいかどうかを確認できます。Cocoaのトピック:Nullの使用を参照してください。

したがって、適切なテストは次のとおりです。

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

titleがnilであっても、title.lengthは0 / nil / false(この場合は0)を返すため、特別な場合を必要としないという事実をどのように使用できるかに注意してください。これは、Objective Cに慣れていない人が慣れていることに問題があります。特に、nilへのメッセージ/メソッド呼び出しがクラッシュする他の言語から来る場合はそうです。


ありがとう!ただし、「タイトル」がnullであるため例外が発生したため、最初にこの質問をしました。
Teo Choong Ping、

1
タイトルはどのタイプのはずですか?たとえば、それがNSStringの場合、次の警告が表示されます:異なるObjective-Cタイプの比較 'struct NSNull *'と 'struct NSString *'にはキャストがありませんこれを削除する方法はありますか?この質問が尋ねられました)?
thebossman 2010

1
コンパイルせずにコードを投稿するのに役立ちます;-)。タイトルはおそらくNSStringですが、タイトルのタイプに関係なく、nullをジェネリックIDタイプ(id)[NSNull null]にキャストするだけです。
Peter N Lewis、

1
@JLT nilと[NSNull null]が同じになることはありません。[NSNull null]は、nilが使用できない場合(たとえば、NSArrayまたはNSDictionary値で)、nilの代わりとして使用できるシングルトンオブジェクトです。したがって、ユースケースは、オプションの文字列のNSArrayがあり、その一部はnullである可能性があり、nullの場合は配列で[NSNull null]を使用します。実際には、テストはほとんど必要ありません。あなた(またはあなたが使用するライブラリ!)が[NSNull null]をプレースホルダーとして積極的に使用している場合のみです。
Peter N Lewis

1
フラッターからここに来る、と理由を探しているMapアイテムの値-あるnullダーツで-に対応していないnilか、NULL理由はそれが実際にあるということでした客観CでNUNull nullはなく、NULLヌル。ありがとう@PeterNLewis!
Aleksandar

25

それはと同じくらい簡単です

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

目的Cでは、objectがnullの場合、値として0を返すことに注意してください。

これにより、ヌル文字列と長さ0の文字列の両方が得られます。


49
オブジェクトがNSNullの場合、これは機能しませんが、最初に明示的に確認する必要があります。
ジェレミーマック

6
NSNullのカテゴリを作成して、長さメッセージに0を返すようにすることもできます:)
Mihai

1
そうです、オブジェクトがNSNullの場合、これはクラッシュします。
Mike Gledhill 2013年

オブジェクトがnsnullをと等しい場合、これはクラッシュします
ジョアン

1
NSNullの認識されないセレクターの問題に加えて、これはnilであるNSStringポインター、または実際にはそこにあるが本質的に空の文字列であるNSStringを区別しません。(たとえば、リテラルobject = @"";またはobject = nil;
KellyTheDude

6

このサイトの次の関連記事を参照してください。

あなたは余分なチェックをする必要がないはずなので、あなたのエラーは何か他のものに関連していると思います。

この関連する質問も参照してください:nil sqliteテキスト列の適切なチェック


不愉快なことに、2番目のハイパーリンク(このサイトの何かにさえ)を追加するのに十分な「ポイント」がありません。以下も参照してください。- stackoverflow.com
questions/598396/…

...私を許して。あなたは担当者0から自分の投稿を編集することができるはずですが
Rogメール

ありがとう-それはとても親切でした。私が最初の投稿を書いたとき、それは新しいユーザーが1つのハイパーリンクしか追加できないようなものだと言いました(これは少し厳しいようです-特にこのサイトのクロスリンクの場合)。
TimM 2009年

6

私は本当にそれを正しく行うためにあなたは似たようなことをしなければならなくなることに気づきました

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

そうしないと、制御がチェックをバイパスするという奇妙な状況が発生します。isEqualと長さのチェックを通過するものに出会ったことはありません。


5

これらすべての「私のために働く」の答えはどうですか?私たちはすべて同じ言語でコーディングしており、ルールは

  1. 参照がnilでないことを確認してください
  2. 文字列の長さが0ではないことを確認してください

それはすべてのために働くでしょう。与えられたソリューションが「うまくいく」場合、それはアプリケーションフローが参照がnullまたは文字列長が0になる可能性があるシナリオを許可しないためです。これを行う適切な方法は、これを処理するメソッドです。すべての場合に必要なもの。


4
参照がnil(注:「null」ではない)の場合、などのメッセージを送信するlengthと、0(またはメソッドの戻り値の型に適切な0値)が生成されます。それが言語のルールです。nilこの場合、個別に確認する必要はありません。
jscs 2013年

私は単にC ++の習慣のためにnullと言いましたが、コードがnilオブジェクトのメソッドを呼び出している場合、コードが壊れている可能性があります。NULL / NIL(同じ概念)でメソッドを呼び出すことは、一般的にどの言語でも悪い考えです。obj-cがそのようなことを可能にするからといって、nilオブジェクトを渡して気にせずにそれらを使用しようとする必要があるだけではありません。
nenchev 2014年

1
長さをnilに送信すると0が生成されますが、NSNullに長さを送信すると例外が生成されます。
cdstamper 2014

@nenchev誰もnilオブジェクトを単に渡すことについては何も述べていませんが、nilをチェックしてからメソッドを呼び出してその戻り値を使用することは、使用することを意図した言語機能を使用してメソッドの戻り値の有効性を後でチェックするよりもIMOが悪いです。
Kevin

@Kevin言語機能が優れていることを意味しないからといって、どれほど実際に悪いかはわかりません。nullがコードパスを開いてランタイムエラーのトレースを困難にする可能性があるかどうかをチェックしない。通常、入力が期待どおりであることを確認し、そうでない場合はそれに応じて対応するのが最善です。個人的には、メッセージをnilオブジェクトに送信しようとしたときにランタイム例外が発生しないという「機能」が好きではありません。実行時のバグを見逃しがちになるためです。
nenchev

4

すべてのnil /空のオブジェクト(空の文字列や空の配列/セットなど)に対してテストする場合は、以下を使用できます。

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
これは実際にはオブジェクト== [NSNull null]をチェックしないため、おそらく意味があります。
ピーターNルイス

3

2つの状況があります。

オブジェクトが[NSNull null]であるか、不可能である可能性があります。
アプリケーションは通常[NSNull null];、「null」オブジェクトを配列に配置したり、ディクショナリ値として使用したりする場合にのみ使用するべきではありません。そして、どの配列またはディクショナリにnull値が含まれている可能性があり、どれが含まれていない可能性があるかを把握する必要があります。
配列に[NSNull null]値が含まれていないと思われる場合は、チェックしないでください。がある場合[NSNull null]、例外が発生する可能性がありますが、問題ありません。Objective-C例外はプログラミングエラーを示します。そして、いくつかのコードを変更して修正する必要があるプログラミングエラーがあります。

オブジェクトが存在する可能性がある場合、[NSNull null]テストするだけでこれを確認できます
(object == [NSNull null])。呼び出すisEqualオブジェクトのクラスのやチェックは意味があり。[NSNull null]オブジェクトは1つしかなく、単純な古いC演算子は、最も簡単で効率的な方法でそれを問題なくチェックします。

NSStringできないオブジェクトを確認した場合(確認[NSNull null]できないため[NSNull null]、またはとは異なることを確認した[NSNull null]ため)、空の文字列、つまり長さが0の文字列をどのように処理するかを自問する必要があります。をnull文字列として扱うとnil(object.length == 0)test。object.lengthは0を返すobject == nilので、このテストはnilのオブジェクトと長さが0の文字列をカバーしますobject == nil

あなたは配列や辞書、およびnilの可能性があり、文字列に文字列を追加したい場合は最後に、あなたは、それを追加することでそれを交換しないの選択持っている@""、またはでそれを置き換えることを[NSNull null]。これを置き換えると@""、「文字列なし」と「長さ0の文字列」を区別できなくなります。これを置き換えると[NSNull null][NSNull null]オブジェクトをチェックする配列または辞書にアクセスするときにコードを記述する必要があります。


非常に長いですが、これは良いことです。NSNullはシングルトンでのみ表示されます!この質問全体は意味をなさず、コーダーが何か正しいことをしていなかったことを教えてくれます。さらに多くの人が、マニュアル/適切なコードプラクティスを読んでいませんでした
Stephen J

2

あなたはnilをチェックするだけです

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

または

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

2

MACROソリューション(2020)

たとえば、UILabelで" (null) "文字列を取得する代わりに、安全な文字列に使用するマクロは次のとおりです。

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

メンバークラスと名前プロパティがあり、名前がnilであるとします。

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

マクロあり:

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

すてきできれい😊

拡張ソリューション(2020)

プロジェクトでnil Nullと空の文字列をチェックしたい場合は、以下の拡張ラインを使用できます。

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

使用例

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

これは、NSString *strOne = @""OR NSString *strOne = @"StackOverflow"OR NSString *strOne = [NSNull null]ORの場合に機能しますNSString *strOne


0

この種のものがまだ存在しない場合は、NSStringカテゴリを作成できます。

@interface NSString (TrucBiduleChoseAdditions)

- (BOOL)isEmpty;

@end

@implementation NSString (TrucBiduleChoseAdditions)

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

@end

それはおそらくやり過ぎであり、それがこの問題を解決することはないと思います。
Rog

9
self == nilは無意味です-selfがnilだった場合、Objective Cはそもそもあなたを呼び出しませんでした。[(NSString *)nil isEmpty]は、コードを呼び出さずに0 / nil / falseを返すだけです。
ピーターNルイス

4
実際、さらに、[(NSString *)nil isEmpty]はfalseを返します。このようなObjective Cメソッドを作成する場合は、nilの0 / nil / falseが意味をなすように定義することをお勧めします。そのため、hasCharactersとしてメソッドを作成する方が適切です。if(!s.isEmpty)とs.lengthはs == nilの場合に正しく0を返すため、if(s.length)を使用したい場所であればどこでも使用できるため、長さはすでに機能しています。
Peter N Lewis

これは重大なクラッシュです。NSStringに「isEmpty」を実装しましたが、実際にNSNullの場合、isEmptyはNSNullに送信され、そのメッセージに応答しないためクラッシュします。
daniel.gindi 2012年

0

私にとってうまくいくのは if ( !myobject )


3
これはnullオブジェクトでは機能せず、nilオブジェクトでのみ機能します。たとえば... 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

エラー。書式設定は申し訳ありませんが、コードはコンパイルされます:)
Rik Smith-Unna

0

null条件の文字列の完全なチェックは次のようになります。<\ br>

    if(mystring)
     {
       if([mystring isEqualToString:@ ""])
        {
          mystring = @ "some string";
        }
     }    
    そうしないと
     {
        //ステートメント
     }

0

私は空の文字列だけをチェックします

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


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

1
このコードスニペットは質問に答えることがありますが、その方法や理由を説明するコンテキストは提供していません。答えを説明するために、1〜2文を追加することを検討してください。
brandonscript

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

0

文字列の場合:

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

}

下の図を参照してください。

ここに画像の説明を入力してください


0

文字列の場合:

+ (BOOL) checkStringIsNotEmpty:(NSString*)string {
if (string == nil || string.length == 0) return NO;
return YES;}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.