2

PersonObjective C では、たとえば、多くのフィールドfirstNamelastNamephoneNumber、... などを持つオブジェクトがありますaddresscityこれらのフィールド タイプはNSStringであり、これらのいずれかである可能性がありますnil

ここで、フィールド値を別のフィールドに連結したいと思いますNSString:

Person *p = ...
NSMutableString *s = [[NSMutableString alloc] init];
for (NSString *field in @[p.firstName, p.lastName, p.phoneNumber,
                          p.adress, p.city, ....more fields...]) {
    if ([field length] > 0) {
        [s appendFormat:@"%@\n", field];
    }
}

問題は、フィールドの 1 つが であるたびに、このコードがクラッシュすることですnil。例外があります:

[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object 
from objects[0]'

ループnil内の値のケースを単純に処理するにはどうすればよいですか?for

4

5 に答える 5

3

@TomPace の投稿に同意します。この少数の場合、単純な if/else を実行します。

ただし、フィールドのリストをループする必要がある場合があります。

配列に値を挿入しようとしている可能性があるため、やみくもに値を配列にプルするのは悪い考えですnil。この場合、フィールド名をキー配列に文字列として配置し、 を使用valueForKey:してリストをループして値にアクセスする方がよいでしょう。keysリストを別の場所に保存して、再び使用できるようにすることもできます。

Person *p = ...
NSMutableString *s = [[NSMutableString alloc] init];

NSArray *keys = @[@"firstName", @"lastName", @"phoneNumber", @"adress", @"city"];

for (NSString *key in keys) 
{
    NSString *value = [p valueForKey:key];
    if ([value length] > 0) {
        [s appendFormat:@"%@\n", value];
    }
}
于 2013-12-09T04:12:09.023 に答える
0

この小さなフィールドの選択には、for ループを使用しないでください。

for ループ構造を試すことでコードを少し節約できるかもしれませんが、少数のフィールドのみで NSArray を構築している場合、特にnil 項目を入れることができないため、実際にはそうする方法ではありません。

より良い方法は次のとおりです。

Person *p = ...
NSMutableString *s = [[NSMutableString alloc] init];
if ([p.firstName length] > 0)   [s appendFormat:@"%@\n", p.firstName];
if ([p.lastName length] > 0)    [s appendFormat:@"%@\n", p.lastName];
if ([p.phoneNumber length] > 0) [s appendFormat:@"%@\n", p.phoneNumber];
if ([p.adress length] > 0)      [s appendFormat:@"%@\n", p.adress];
if ([p.city length] > 0)        [s appendFormat:@"%@\n", p.city];

Edit、元の質問が大量のフィールドで更新された後。@BergQuester が言ったように、より大規模な任意のフィールド セットをサポートするアプローチは、KVO スタイルの検査を使用することです。

NSArray *fieldNames = @[@"firstName", @"lastName", @"phoneNumber", ....more fields...];
NSString *field;
for (NSString *fieldName in fieldNames) {
    field = [p valueForKey:fieldName];
    if ([field length] > 0 ) {
        [s appendFormat: @"%@\n", field];
    }
}
于 2013-12-09T04:08:38.093 に答える
0

NSMutableStringカテゴリを作成してみる

#import "NSMutableString+checkForNilObject.h"

@implementation NSMutableString (checkForNilObject)


-(void) appendNotNillObject:(NSString *) string
{
    if(string)
    {
       [self appendString:string];
    }
}
@end
于 2013-12-09T05:27:34.367 に答える
0

クラスのゲッターをオーバーライドできますPerson

    @implementation Person

    - (NSString *)firstName{
        if (_firseName == nil)
             _firstName = @"";
        return _firstName;
    }
///....Other setters    

    @end

このように、ここですべてのセッターを定義できます。

于 2013-12-09T05:09:39.017 に答える
0
Person *person = [[Person alloc] init];
person.firstName = nil;
person.lastName = @"lastName";

NSMutableString *s = [[NSMutableString alloc] init];
[s appendFormat:@"%@\n", person.firstName == nil?@"":person.firstName];
[s appendFormat:@"%@\n",  person.lastName == nil?@"":person.lastName];
于 2013-12-09T04:27:34.847 に答える