创建NSArray以表示包含nil的值

时间:2016-03-03 16:06:03

标签: objective-c cocoa cocoa-touch nsarray variadic-functions

我有数据源方法,要求NSArray个数字;其中一些可能是nil,但无论如何我都需要返回每个值。

该方法可能如下所示:

- (NSArray *)configurationValues:(Configuration *)configuration {
  ....  
  return [NSArray arrayWithObjects:value1, value2, value3, value4, nil];
}

如果value3nil,我必须返回{2,3,(对象为零),3}。

当然我收到异常,因为我无法插入nil对象

我可以做的是检查每个对象并插入一些虚拟数字或NSNull,但这对我来说似乎是样板,并不是很优雅。

我正在尝试为NSArray创建一个类别,该类别会用其他内容替换所有nil值以避免例外:

@implementation NSArray (Nullable)

+ (instancetype)arrayWithObjectsSafe:(id)firstObj, ... {
    NSMutableArray *array = [NSMutableArray array];
    va_list args;
    id  object;

    va_start(args, firstObj);

    while((object = va_arg(args, id))) {
        if (object) {
            [array addObject:object];
        } else {
            // Insert dummy element // stuck here
            [array addObject:[NSNull null]];
        }
        NSLog(@"OBJECT %@", object);

    }

    va_end(args);
    return [NSArray arrayWithArray:array];
}
@end

我对variadic方法并不熟悉,因为while循环跳过了nil值,所以我被困在这里,所以最后一个数组只包含nil之前的元素}。

我是否可以解决此问题,或者NSArray是否存在尝试插入nil对象时不会抛出异常的方法?

2 个答案:

答案 0 :(得分:4)

您的代码失败只是因为您使用nil作为参数结束标记和参数之一。只需使用不同的参数结束标记。例如,您可以定义:

const id END_MARKER (__bridge id)(void *)-1;

定义另一个常量而不是nil(其值为0)。将你的循环改为:

while((object = va_arg(args, id)) != END_MARKER)

并致电:

[NSArray arrayWithObjects:value1, value2, value3, value4, END_MARKER];

并且您的代码有效。

HTH

答案 1 :(得分:0)

嗯,那不行。如果对象列表中存在NULL,则循环将把它作为列表的末尾。它不会崩溃,但它也不会添加[NSNull null]。

检查和value1一样简单吗?:[NSNull null]而不是value1。