Why is __strong required in fast enumeration loops with ARC

后端 未结 2 1764
予麋鹿
予麋鹿 2020-12-18 09:44

When I do something simialr to the following I get an error saying

for (UIView* att in bottomAttachments) {
    if (i <= [cells count]) {
        att = [         


        
相关标签:
2条回答
  • 2020-12-18 10:03

    If a variable is declared in the condition of an Objective-C fast enumeration loop, and the variable has no explicit ownership qualifier, then it is qualified with const __strong and objects encountered during the enumeration are not actually retained.

    Rationale
    This is an optimization made possible because fast enumeration loops promise to keep the objects retained during enumeration, and the collection itself cannot be synchronously modified. It can be overridden by explicitly qualifying the variable with __strong, which will make the variable mutable again and cause the loop to retain the objects it encounters.

    source

    As Martin noted in a comment, it's worth noting that even with a __strong variable, by reassigning it you won't modify the array itself, but you'll just make the local variable point to a different object.

    Mutating an array while iterating on it is generally a bad idea in any case. Just build a new array while iterating and you'll be fine.

    0 讨论(0)
  • 2020-12-18 10:20

    Why are you assigning a new value to that pointer anyway? Are you trying to replace an object in the array? In that case you need to save what you want to replace in a collection and do it outside the enumeration since you can't mutate an array while enumerating.

    NSMutableDictionary * viewsToReplace = [[NSMutableDictionary alloc] init];
    NSUInteger index = 0;
    
    for(UIView * view in bottomAttachments){
        if (i <= [cells count]) {
            // Create your new view
            UIView * newView = [[UIView alloc] init];
            // Add it to a dictionary using the current index as a key
            viewsToReplace[@(index)] = newView;
        }
        index++;
    }
    
    // Enumerate through the keys in the new dictionary
    // and replace the objects in the original array
    for(NSNumber * indexOfViewToReplace in viewsToReplace){
        NSInteger index = [indexOfViewToReplace integerValue];
        UIView * newView = viewsToReplace[indexOfViewToReplace];
        [array replaceObjectAtIndex:index withObject:newView];
    }
    
    0 讨论(0)
提交回复
热议问题