如何安全地将对象放在__unsafe_unretained数组中?

时间:2014-07-31 17:24:39

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

我正在尝试处理和更改NSDictionary的键,同时保留相同的对象。最好的方法似乎是使用-getObjects:andKeys:,修改键数组,然后用+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);

1 个答案:

答案 0 :(得分:2)

你是对的(我的第一个答案是错的)。为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;
}];

(旧错误答案已删除)