2016-06-27 3 views
2

someData[start...stop]MutableRandomAccessSlice을 반환한다는 사실에 정말로 고심하고 있습니다. 내 someDatalet 이었으므로 왜 내가 변덕스러운 것을 원하겠습니까? 내가 RandomAccessSlice을 얻는 이유는 무엇입니까? 정말 실망 스럽지만 원래 API와 호환되지 않는 API를 반환한다는 것입니다. Data을 사용하면 .withUnsafeBytes을 사용할 수 있지만이 새끼는 사용할 수 없습니다. 그리고 어떻게 슬라이스를 다시 데이터로 바꾸는지는 명확하지 않습니다. 그것들 중 하나를 취하는 init은 없다.데이터 <-> MutableRandomAccessSlice

서브 스크립팅 대신 subdata(in:) 메서드를 사용할 수 있지만 원래 컬렉션처럼 동작하는 하위 컬렉션 표현 만 원할 경우 하위 스크립트의 요점은 무엇입니까? 또한 subdata 메서드는 열린 하위 범위 만 수행 할 수 있으며, 아래 첨자는 닫히고 열 수 있습니다. Swift3 결승전에서 아직 마무리하지 못한 것입니까?

답변

4

돌아 오는 MutableRandomAccessSlice값인 유형이며 참조 유형이 아닙니다. 그것은 단지 당신이 좋아하는 경우에 당신이 그것을 수정할 수 있다는 것을 의미하지만,이 일에 아무런 당신이 밖으로 슬라이스가 없습니다 : 당신은 code를 보면

let x = Data(bytes: [1,2,3]) // <010203> 
var y = x[0...1] 
y[0] = 2 
x // <010203> 

, 당신이 의도를 반환하는 것입니다 있습니다 것을 맞춤 슬라이스 유형 :

public subscript(bounds: Range<Index>) -> MutableRandomAccessSlice<Data> { 
    get { 
     return MutableRandomAccessSlice(base: self, bounds: bounds) 
    } 
    set { 
     // Ideally this would be: 
     // replaceBytes(in: bounds, with: newValue._base) 
     // but we do not have access to _base due to 'internal' protection 
     // TODO: Use a custom Slice type so we have access to the underlying data 
     let arrayOfBytes = newValue.map { $0 } 
     arrayOfBytes.withUnsafeBufferPointer { 
      let otherData = Data(buffer: $0) 
      replaceBytes(in: bounds, with: otherData) 
     } 
    } 
} 

즉, 맞춤 슬라이스는 여전히 데이터를 사용하는 기능에 적합하지 않습니다. Array와 같은 다른 유형과도 일관성이 있습니다. Array는 ArraySlice로 분할되며 Array는 Array가 예상되는 곳으로 전달 될 수 없습니다. 이것은 설계 상으로는 (그리고 같은 이유로 데이터 용으로도 가능합니다). 문제는 슬라이스가 그것을 뒷받침하는 모든 메모리를 "고정"한다는 것입니다. 따라서 메가 바이트 데이터에서 3 바이트 슬라이스를 가져와 ivar로 저장하면 전체 메가 바이트가 중단됩니다. 이론은 (내가 말한 Swift devs에 따르면) 배열은 방대 할 수 있기 때문에 String을 대단히 작게 만드는 동안 조심해야 할 필요가 있으므로 String을 String으로 조각하는 것이 좋습니다.

지금까지 경험 한 바에 따르면 일반적으로 subdata(in:)이 필요합니다. 내 실험은 슬라이싱 속도와 매우 비슷하기 때문에 쓰기에 여전히 사본이라고 생각합니다.하지만 초기 테스트에서 메모리를 고정하지는 않습니다. 나는 지금까지 맥에서 테스트를 해왔다. iOS 기기의 성능 차이가 더 클 수 있습니다. 롭의 의견을 바탕으로

+0

을 할 수있는 방법! –

0

, 방금 다음 pythonesque 첨자 확장자를 추가 :

extension Data { 
    subscript(start:Int?, stop:Int?) -> Data { 
     var front = 0 
     if let start = start { 
      front = start < 0 ? Swift.max(self.count + start, 0) : Swift.min(start, self.count) 
     } 
     var back = self.count 
     if let stop = stop { 
      back = stop < 0 ? Swift.max(self.count + stop, 0) : Swift.min(stop, self.count) 
     } 
     if front >= back { 
      return Data() 
     } 
     let range = Range(front..<back) 
     return self.subdata(in: range) 
    } 
} 

난 그냥

이 매우 명확하고 간결하게 대답
let input = Data(bytes: [0x60, 0x0D, 0xF0, 0x0D]) 
input[nil, nil] // <600df00d> 
input[1, 3]  // <0df0> 
input[-2, nil] // <f00d> 
input[nil, -2] // <600d> 
관련 문제