Swift数组元素地址

时间:2014-10-16 03:55:14

标签: arrays swift nsdata

这是一个实际的问题,我发送一个文件,将其分成1000个字节的中继

data = NSData.dataWithContentsOfFile(path)
var dataPackage : [Byte](count: 1000, repeatedValue: 0)

for offset = 0; offset < data.length; {
     // omit some range check here
     data.getBytes(&dataPackage, NSRange(location: offset, length: 1000))
     send(dataPackage)
}

一切都很棒,直到我想在0位置的dataPackage中插入一个序列号,所以很自然地,我会将上面的内容更改为

data.getBytes(&dataPackage[1], NSRange(location: offset, length: 999))

事实证明,只有1个元素被复制到dataPackage。剩下的999个元素被复制到dont-know-where

我的问题是,1)如何使这项工作,以及2)如何解决swift中的数组,以及&amp; data [i] =&amp; data + i(如第1个例子所示)但是&amp; data [i + k]!=&amp; data [i] + k

编辑:我通过

解决了(1)
data.getBytes(&dataPackage + 1, NSRange(location: offset, length: 999))

问题(2)仍然存在

1 个答案:

答案 0 :(得分:3)

我认为不要getBytes(&dataPackage[i] + k, ..),这可能会导致“访问违规”

考虑以下代码:

struct MyStruct {
    var _val = [Int](count: 1000, repeatedValue: 0);
    subscript(idx:Int) -> Int {
        get {
            println("get: [\(idx)] -> val(\(_val[idx]))")
            return _val[idx]
        }
        set(val) {
            println("set: [\(idx)] old(\(_val[idx])) -> new(\(val))")
            _val[idx] = val
        }
    }
}

func myFunc(ptr:UnsafeMutablePointer<Int>, val:Int) {
    println("mutating: ptr(\(ptr)) <- \(val)")
    ptr.memory = val
}

MyStruct只是Array的包装。

myFunc收到一个可变指针,并改变它的值。

有了这个,当你做的时候:

var foo = MyStruct()
myFunc(&foo[1], 12)

输出:

get: [1] -> val(0)
mutating: ptr(0x00007fff561619d8) <- 12
set: [1] old(0) -> new(12)

请参阅?

  1. 值复制到somewhere
  2. 变异 somewhere
  3. 的值 来自somewhere
  4. 回写

    我不知道somewhere在哪里。

    当你这样做时:

    var foo = MyStruct()
    myFunc(&foo[1] + 1, 12)
    

    输出:

    get: [1] -> val(0)
    set: [1] old(0) -> new(0)
    mutating: ptr(0x00007fff5c0b79e0) <- 12
    

    这一次,我的猜测是:

    1. 值复制到somewhere
    2. corruptedsomewhere + 1
    3. 来自somewhere未更改值
    4. 回写
    5. 放弃somewhere
    6. 变异 corrupted
    7. 的值

      另一方面,当你这样做时:

      var foo = [Int](count:1000, repeatedValue:0)
      myFunc(&foo + 1, 12)
      

      这意味着:

      1. ptr作为foo
      2. 的第一个元素的指针
      3. ptrptr + 1
      4. 变异 ptr
      5. 的值

        因此,foo[1]将成功12

        the document.

        中提到的,&的实际内容(Array)非常特殊
          

        当一个函数声明为接受UnsafeMutablePointer参数时,它可以接受以下任何一个:

             
            
        • nil,作为空指针传递
        •   
        • UnsafeMutablePointer值
        •   
        • 一个输入输出表达式,其操作数是类型为Type的存储左值,它作为左值的地址传递
        •   
        • 输入输出[类型]值,作为指向数组开头的指针传递,并在调用期间延长生命周期
        •   

        只有内置Array具有最后一项功能。

        因此,当您将&notAnArrayLvalue(包括&array[i])传递给UnsafeMutablePointer<Type>参数时,长度应始终为1,您不应该+-它。