【问题标题】:Creating an NSArray to represent values that include nil创建一个 NSArray 来表示包含 nil 的值
【发布时间】:2016-06-17 01:44:33
【问题描述】:

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

该方法可能如下所示:

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

如果value3nil,我必须返回 {2, 3, (object is nil), 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

我对可变参数方法不是很熟悉,因为while 循环跳过了nil 值,所以最终数组只包含nil 之前的元素。

我可以解决这个问题,还是有一种现有的方法让NSArray 在尝试插入nil 对象时不引发异常?

【问题讨论】:

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


    【解决方案1】:

    您的代码失败只是因为您使用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

    【讨论】:

      【解决方案2】:

      好吧,那是行不通的。如果您的对象列表中有一个 NULL,您的循环将把它作为列表的结尾。它不会崩溃,但也不会添加 [NSNull null]。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-07-13
        • 2021-10-07
        • 1970-01-01
        • 2011-06-19
        • 2019-07-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多