Why retain/release pair is not removed in this particular case?

This is because for loops use consuming iteration, which needs to copy the array. There are two ways to solve this:

  1. A smarter optimiser. If you compile with -Xfrontend -enable-ossa-modules, the copy gets optimised away, and the d function does not contain any retains or releases.

    While it's interesting (and it proves that this is solvable by the compiler), it's probably not a great idea to ship things built using experimental compiler flags. The optimiser team have said they are working on improving this mode, so hopefully it will be enabled by default before too long :crossed_fingers:

  2. Use an index-based loop instead:

    func d() {
        for t in 0..<self.b.count {
            self.b[t].take(a: self.a)
        }
    }
    

    Not as pretty as using the for loop directly on the array, but it avoids consuming the array and therefore also does not contain any ARC operations.

6 Likes