Bibi's DevLog 🤓🍎

[Swift] ArraySlice(SubSequence) - 배열의 부분 참조하기 본문

📱🍎 iOS/🍏 Apple Developer Documentation

[Swift] ArraySlice(SubSequence) - 배열의 부분 참조하기

비비 bibi 2022. 12. 6. 12:36

Apple Developer Documentation

개요

  • ArraySlice는 큰 배열의 부분에 대한 연산을 빠르고 효과적으로 수행하도록 도와준다.
    • 배열의 요소들을 새로운 공간에 복사하는 대신, ArraySlice는 저장된 배열에 대한 참조를 나타내기 때문이다.
  • Array와 동일한 인터페이스를 제공하므로, 일반적으로 원본 배열과 똑같은 연산을 slice에 대해서도 사용할 수 있다.

Subsequence는 원본 collection과 인덱스를 공유한다.

Sharing indices between collections and their subsequences is an important part of the design of Swift’s collection algorithms.

ArraySlice의 인덱스는 항상 0부터 시작하지 않는다.

왜? ArraySlice는 원본과 인덱스를 공유하기 때문. 이는 Swift의 컬렉션 알고리즘 디자인의 핵심이다.

이는 원본 배열(더 큰 배열)이든 ArraySlice이든, 인덱스에 기반한 연산을 동일하게 적용할 수 있도록 하기 위함이다.

ArraySlice의 시작 인덱스와 끝 인덱스를 안전하게 참조하고 싶다면, 항상 특정 값 대신 startIndexendIndex프로퍼티를 사용하십시오.

중요 - ArraySlice와 메모리 누수

ArraySlice를 장기적으로 저장(Long-term storage)하는 것은 지양된다.

그 이유는, ArraySlice는 배열의 부분이 아닌 전체에 대한 참조를 유지하기 때문이다. 이는 심지어 원본 배열이 사라진 이후에도 유지된다.

따라서 ArraySlice를 장기적으로 저장하면 더 이상 접근할 수 없는 요소의 수명이 연장될 수 있으며, 이는 메모리 및 객체 누수로 이어질 수 있다.

예제1

let originalArray = [1, 2, 3, 4, 5]
let arraySlice = originalArray[1...3] // Array<Int>.SubSequence

print(arraySlice) // [2, 3, 4]
print(arraySlice[1]) // 2
print(arraySlice[0]) // Fatal error: Index out of bounds

예제2

매 시간 학급에서 결석한 학생 수를 나타낸 배열이 있을 때, 처음4시간과 끝4시간 중 언제 결석이 더 많았는지 알고 싶다.

let absences = [0, 2, 0, 4, 0, 3, 1, 0]

let midpoint = absences.count / 2

let firstHalf = absences[..<midpoint] // ArraySlice
let secondHalf = absences[midpoint...]

let firstHalfSum = firstHalf.reduce(0, +)
let secondHalfSum = secondHalf.reduce(0, +)

if firstHalfSum > secondHalfSum {
    print("More absences in the first half.")
} else {
    print("More absences in the second half.")
}
// Prints "More absences in the first half."