programing

Swift: 어레이를 참조로 전달하시겠습니까?

lovejava 2023. 4. 19. 21:50

Swift: 어레이를 참조로 전달하시겠습니까?

스위프트에 합격하고 싶다Array account.chats로.chatsViewController.chats참조에 의해 (채팅을 추가할 때)account.chats,chatsViewController.chats여전히 가리키다account.chats즉, Swift가 2개의 어레이를 분리하지 않는 것이 좋습니다.account.chats변화들.

함수 매개 변수 연산자의 경우 다음을 사용합니다.

let (기본 연산자이므로 let을 생략할 수 있습니다) 파라미터를 일정하게 합니다(로컬복사조차 수정할 수 없습니다).

var 변수화(로컬로 수정할 수 있지만 함수에 전달된 외부 변수에는 영향을 미치지 않음)

inout in-out 파라미터로 설정합니다.In-out은 실제로 값이 아닌 참조로 변수를 전달하는 것을 의미합니다.또한 참조에 의한 가치 수용뿐만 아니라 참조에 의한 가치 전달도 요구되므로 다음과 같이 전달합니다.foo(&myVar)뿐만 아니라foo(myVar)

다음과 같이 합니다.

var arr = [1, 2, 3]

func addItem(_ localArr: inout [Int]) {
    localArr.append(4)
}

addItem(&arr)    
print(arr) // it will print [1, 2, 3, 4]

정확히 말하면, 이것은 참조뿐만 아니라 외부 변수의 실제 별칭이기 때문에, 예를 들어 정수(새로운 값을 할당할 수 있음)를 사용하여 이러한 트릭을 수행할 수 있습니다. 단, 이는 좋은 프랙티스가 아닐 수도 있고 이와 같이 원시 데이터 유형을 수정하는 것은 혼란스러울 수 있습니다.

Swift의 구조체는 값으로 전달되지만inout어레이를 수정하는 수식자(아래 답변 참조).클래스는 참조로 통과됩니다. Array그리고.DictionarySwift는 구조체로 구현됩니다.

자신을 정의하다BoxedArray<T>를 실장합니다.Array인터페이스를 지정하지만 모든 기능을 저장된 속성에 위임합니다.그렇게 해서

class BoxedArray<T> : MutableCollection, Reflectable, ... {
  var array : Array<T>

  // ...

  subscript (index: Int) -> T { 
    get { return array[index] }
    set(newValue) { array[index] = newValue }
  }
}

를 사용합니다.BoxedArray사용할 수 있는 곳이면 어디든Array. 의 할당BoxedArray참조가 됩니다.클래스이기 때문에 저장 속성에 변경이 가해집니다.Array모든 참조에 표시됩니다.

Swift 버전 3-4(XCode 8-9)의 경우

var arr = [1, 2, 3]

func addItem(_ localArr: inout [Int]) {
    localArr.append(4)
}

addItem(&arr)
print(arr)

뭐랄까

var a : Int[] = []
func test(inout b : Int[]) {
    b += [1,2,3,4,5]
}
test(&a)
println(a)

???

또 하나의 옵션은 어레이의 소비자에게 필요에 따라 어레이를 요구하도록 하는 것입니다.예를 들어 다음과 같은 것이 있습니다.

class Account {
    var chats : [String]!
    var chatsViewController : ChatsViewController!

    func InitViewController() {
        chatsViewController.getChats = { return self.chats }
    }

}

class ChatsViewController {
    var getChats: (() -> ([String]))!

    func doSomethingWithChats() {
        let chats = getChats()
        // use it as needed
    }
}

그런 다음 계정 클래스 내에서 원하는 만큼 배열을 수정할 수 있습니다.뷰 컨트롤러 클래스에서 어레이를 수정하는 경우에도 이 방법은 도움이 되지 않습니다.

사용.inout하나의 솔루션이지만 어레이는 가치 타입이기 때문에 그다지 신속하다고는 생각하지 않습니다.문체적으로 저는 개인적으로 변환된 복사본을 반환하는 것을 선호합니다.

func doSomething(to arr: [Int]) -> [Int] {
    var arr = arr
    arr.append(3) // or likely some more complex operation
    return arr
}

var ids = [1, 2]
ids = doSomething(to: ids)
print(ids) // [1,2,3]

NSMutableArray ★★★NSArray, 클래스입니다.

이렇게 하면 Wraper를 삽입할 필요가 없으며 빌드를 사용하여 브리징할 수 있습니다.

open class NSArray : NSObject, NSCopying, NSMutableCopying, NSSecureCoding, NSFastEnumeration

으로 합니다.BoxedArray정답, 나는 나를 위해 아래 클래스를 만들었다.어레이를 참조로서 자유롭게 전달할 수 있는 것이 마음에 듭니다(다른 언어도 마찬가지).

class MArray<T> : MutableCollection {
    
    var array : Array<T> = Array()
    var count: Int { return array.count }   // getter (without, index func below will be called repeatedly to determine)
    
    func add(_ value: T) {
        array.append(value)
    }

    // MutableCollection requires:
    subscript (index: Int) -> T {
      get { return array[index] }
      set(value) { array[index] = value }
    }
    var startIndex: Int {
        return 0
    }
    var endIndex: Int {
        return array.count
    }
    func index(after i: Int) -> Int {
        return i+1
    }
}

언급URL : https://stackoverflow.com/questions/24250938/swift-pass-array-by-reference