Swift与Objective C指针操作问题 [英] Swift vs Objective C pointer manipulation issue

查看:78
本文介绍了Swift与Objective C指针操作问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在目标C中有以下代码,它可以正常工作:

I have this code in Objective C which works fine:

list = controller->audioBufferList;
list->mBuffers[0].mDataByteSize = inNumberFrames*kSampleWordSize;
list->mBuffers[1].mDataByteSize = inNumberFrames*kSampleWordSize;

效果很好,它更新了mBuffers [0]的mDataByteSize字段; mBuffers [1]。我试过在Swift中翻译相同的内容,但不起作用:

And it works fantastic, it updates mDataByteSize field of mBuffers[0] & mBuffers[1]. I tried translating the same in Swift but it doesn't work:

public var audioBufferList:UnsafeMutableAudioBufferListPointer

在功能上,

let listPtr = controller.audioBufferList.unsafeMutablePointer

let buffers = UnsafeBufferPointer<AudioBuffer>(start: &listPtr.pointee.mBuffers, count: Int(listPtr.pointee.mNumberBuffers))

for var buf in buffers {
    buf.mDataByteSize = inNumberFrames * UInt32(sampleWordSize)
    NSLog("Data byte size \(buf.mDataByteSize)")
}

for buf in buffers {
    NSLog("Data byte size \(buf.mDataByteSize)")
}

mDataByteSize不更新。 NSLog在第二次读回for循环时指向原始值,而不是更新的值。似乎var buf通过复制来引用另一个buf。我如何解决它?这是我无法理解的纯Swift语言问题。

The mDataByteSize is not updated. The NSLog on reading back in second for loop points to original values, not updated ones. It seems var buf is referring to another buf by making a copy. How do I fix it? It's a pure Swift language issue that I am not able to understand.

编辑:正如Martin所指出的,我通过将for循环修改为

As pointed out by Martin, I fixed the issue by modifying the for loop as

 for i in 0..<Int(listPtr.pointee.mNumberBuffers) {
    buffers[i].mDataByteSize = inNumberFrames * UInt32(sampleWordSize)
}

现在可以使用了。但是,这进一步激起了我对Swift语言的好奇心,它对使用指针来操纵东西的开发人员来说是多么的不直观,以及多么令人讨厌。为什么以下循环失败? var缓冲区是否按值复制?

Now it works. But that has further aroused my curiosity in Swift Language, how non intuitive it is and how irritating it is for developers who use pointers to manipulate stuff. Why do the following loops fail? Are the var buffers copy by value?

     for buf in buffers {
         var buffer = buf
         buffer.mDataByteSize = inNumberFrames * UInt32(sampleWordSize)
     }

Or

    for var buf in buffers {
        buf.mDataByteSize = inNumberFrames * UInt32(sampleWordSize)
    }

编辑2:Hamish的回答使人们怀疑在任何地方使用listPtr的有效性。我在许多调用中都使用了listPtr,例如:

EDIT 2: Hamish's answer raises doubts about validity of using listPtr anywhere. I was using listPtr in a number of calls, such as:

let status = AudioUnitRender(controller.audioUnit!, ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, listPtr)

我现在需要知道在哪里可以使用listPtr,在哪里可以使用

I now need to know where can we use listPtr and where we can not!

推荐答案

通话:

let buffers = UnsafeBufferPointer<AudioBuffer>(start: &listPtr.pointee.mBuffers, count: Int(listPtr.pointee.mNumberBuffers))

& listPtr.pointee.mBuffers 产生一个临时指针,该指针仅在对<$ c $的调用期间有效c> UnsafeBufferPointer 的初始化程序。因此,尝试使用缓冲区指针会导致未定义的行为(编译器将会希望能在Swift 5.1中警告此类情况

&listPtr.pointee.mBuffers produces a temporary pointer valid only for the duration of the call to UnsafeBufferPointer's initialiser. Therefore attempting to use the buffer pointer results in undefined behaviour (the compiler will hopefully warn on such cases in Swift 5.1).

相反,您可以直接在 UnsafeMutableAudioBufferListPointer 上进行迭代,因为它符合 MutableCollection

Instead, you can iterate directly over UnsafeMutableAudioBufferListPointer, as it conforms to MutableCollection.

例如:

for index in audioBufferList.indices {
  audioBufferList[index].mDataByteSize = inNumberFrames * UInt32(sampleWordSize)
  print("Data byte size \(audioBufferList[index].mDataByteSize)")
}

for buffer in audioBufferList {
  print("Data byte size \(buffer.mDataByteSize)")
}

这篇关于Swift与Objective C指针操作问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆