Objective c 浏览对象';s场

Objective c 浏览对象';s场,objective-c,for-loop,nsnull,Objective C,For Loop,Nsnull,在目标C中,我有一个对象,例如Person,它有许多字段firstName,lastName,电话号码,地址,城市。。。等等这些字段类型是NSString,其中任何一个都可以是nil 现在我想将我的字段值连接到另一个NSString: Person *p = ... NSMutableString *s = [[NSMutableString alloc] init]; for (NSString *field in @[p.firstName, p.lastName, p.phoneNumbe

在目标C中,我有一个对象,例如
Person
,它有许多字段
firstName
lastName
电话号码
地址
城市
。。。等等这些字段类型是
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];
    }
}
问题是,只要其中一个字段为
nil
,该代码就会崩溃。我有一个例外:

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

如何简单地处理
for
循环中
nil
值的情况?

对于如此小的字段选择,不要使用for循环

通过尝试for循环结构,您可能节省了一些代码,但如果您仅使用几个字段构建NSArray,那么这确实不是一种可行的方法,尤其是因为不能在其中放置零项

更好的方法是:

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

编辑,在原始问题被大量字段更新后。 正如@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];
    }
}

我同意@TomPace的帖子,对于这个小数字,我会做一个简单的if/else

但是,有时确实需要在字段列表中循环

盲目地将值拉入数组是个坏主意,因为您可能试图将
nil
值插入数组。在这种情况下,最好将字段名作为字符串放入键数组中,并使用
valueForKey:
在列表中循环访问值。我可能会将
列表存储在其他可以再次使用的地方

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

您可以重写类
Person
的getter

    @implementation Person

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

    @end

这样,您就可以在这里定义所有的setter。

尝试创建
NSMutableString
类别

#import "NSMutableString+checkForNilObject.h"

@implementation NSMutableString (checkForNilObject)


-(void) appendNotNillObject:(NSString *) string
{
    if(string)
    {
       [self appendString:string];
    }
}
@end

为了清晰起见,编辑了我的问题:对象中会有很多字段(大约15个)好吧,这意味着我必须更改我的答案:)@Tom Yep,对不起,我的示例太具体了。我看到我的计票数先升后降。有人投票否决了我,我失去了2分。。无论如何,我更新了我的答案,使其更加完整。不是我,投票给你,并保留了它:-)这些是获取者,而不是设定者。此外,这个解决方案浪费内存,可能会产生负面副作用。
>0是多余的(没有错,只是指出另一个风格选项。)@AaronBrager谢谢,是的,你是对的。我想我只是按照原来问题的风格。我更喜欢我自己。
#import "NSMutableString+checkForNilObject.h"

@implementation NSMutableString (checkForNilObject)


-(void) appendNotNillObject:(NSString *) string
{
    if(string)
    {
       [self appendString:string];
    }
}
@end