【问题标题】:How do I safely put an object in an __unsafe_unretained array?如何安全地将对象放入 __unsafe_unretained 数组中?
【发布时间】:2014-07-31 17:24:39
【问题描述】:

我正在尝试处理和更改 NSDictionary 的键,同时保留相同的对象。最好的方法似乎是使用-getObjects:andKeys:s,修改键数组,然后使用+dictionaryWithObjects:forKeys:count: 创建一个新字典来重建字典。但是,对象和键的数组是id __unsafe_unretained []。有没有办法让我安全地将新的键对象分配到该数组中,还是我必须创建另一个数组 id __strong []

以下示例在最后一行出现 EXC_BAD_ACCESS 崩溃:

NSDictionary *old = @{@"key1": @"foo", @"key2": @"bar"};

id __unsafe_unretained keys[2];
id __unsafe_unretained vals[2];
[old getObjects:vals andKeys:keys];

for (NSUInteger i = 0; i < 2; i++) {
    keys[i] = [keys[i] uppercaseString];
}

NSDictionary *new = [NSDictionary dictionaryWithObjects:vals forKeys:keys count:2];

NSLog(@"New dict: %@", new);

【问题讨论】:

    标签: objective-c memory-management automatic-ref-counting nsdictionary


    【解决方案1】:

    你是对的(我的第一个答案是错误的)。为keys[i] 分配一个新值 不保留对象,因此您应该为键创建一个新数组:

    NSDictionary *old = @{@"key1": @"foo", @"key2": @"bar"};
    
    id __unsafe_unretained keys[2];
    id newKeys[2];
    id __unsafe_unretained vals[2];
    [old getObjects:vals andKeys:keys];
    
    for (NSUInteger i = 0; i < 2; i++) {
        newKeys[i] = [keys[i] uppercaseString];
    }
    
    NSDictionary *new = [NSDictionary dictionaryWithObjects:vals forKeys:newKeys count:2];
    

    或者,您可以枚举旧字典并创建新字典 先后:

    NSMutableDictionary *newDict = [NSMutableDictionary dictionary];
    [old enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
        key = [key uppercaseString];
        newDict[key] = obj;
    }];
    

    (旧的错误答案已删除)

    【讨论】:

    • 是的,但不能在分配和调用-dictionaryWithObjects:forKeys:count:之间释放它们吗?
    • @jtbandes:不,因为旧字典也有很强的引用。
    • 对于旧键,是的,但不是对于我分配到 keys 数组中的任何新对象。
    • @jtbandes:你是对的,我的错。用替代建议更新了答案。
    • 作为一个假设的代码读者,我更喜欢enumerateKeysAndObjectsUsingBlock: 选项。
    猜你喜欢
    • 1970-01-01
    • 2021-07-18
    • 2021-09-10
    • 2016-08-06
    • 2013-07-06
    • 1970-01-01
    • 2022-12-18
    • 2021-08-22
    • 1970-01-01
    相关资源
    最近更新 更多