了解UnsafeMutablePointers以及如何处理它们

时间:2017-08-31 16:49:11

标签: swift pointers

有人可以解释一下 UnsafeMutablePointer 的好指南的链接吗?我无法理解他们的工作方式以及如何修改它们。

以下是一个例子。

我正在将自定义视频播放器从 Objective-C 迁移到 Swift

Objective-C 中,我使用回调结构创建 MTAudioProcessingTapRef

MTAudioProcessingTapCallbacks callbacks;
callbacks.clientInfo = (__bridge void *)(self);
callbacks.init = initTap;
// Init other fields of callbacks
MTAudioProcessingTapCreate(kCFAllocatorDefault, &callbacks, kMTAudioProcessingTapCreationFlag_PostEffects, &tap);

在这里,我将可保留的 MyClass 指针转换为void指针,以便稍后将其用作 clientInfo

  

(__ bridge T)op将操作数转换为目标类型T.如果T是a   不可保留的指针类型,然后op必须有一个可保留的对象   指针类型。

然后点按进行初始化:

void initTap(MTAudioProcessingTapRef tap, void *clientInfo, void **tapStorageOut)
{
    *tapStorageOut = clientInfo;
}

在这里,我将一个指向self的指针传递给tapStorageOut ,以便在tap的回调函数中获取自我。

然后执行处理:

void processTap(MTAudioProcessingTapRef tap, CMItemCount numberFrames, MTAudioProcessingTapFlags flags, AudioBufferList *bufferListInOut,
         CMItemCount *numberFramesOut, MTAudioProcessingTapFlags *flagsOut)
{
    MyClass *self = (__bridge MyClass *) MTAudioProcessingTapGetStorage(tap);
    MTAudioProcessingTapGetSourceAudio(tap, numberFrames, bufferListInOut, flagsOut, NULL, numberFramesOut);
}

现在我有一些问题。

  1. 我确实找到了如何将类型转换为其他类型。以下是功能:

    func bridge<type : AnyObject>(object : type) -> UnsafeRawPointer
    {
        let unmanagedObject : Unmanaged = Unmanaged.passUnretained(object)
        let unsafeMutableRawObject : UnsafeMutableRawPointer = unmanagedObject.toOpaque()
        return UnsafeRawPointer(unsafeMutableRawObject)
    }
    
    func bridge<type : AnyObject>(pointer : UnsafeRawPointer) -> type
    {
        let unmanagedObject : Unmanaged<type> = Unmanaged<type>.fromOpaque(pointer)
        let object : type = unmanagedObject.takeUnretainedValue()
        return object
    }
    

    但我对所有这些字母的作用都不了解。你们其中一个人对此的一些解释会很棒。

  2. 让我们看看 initTap 功能。这里我有一个指针A( tapStorageOut ),它引用一个引用某些数据的指针B.我将指针B更改为指针C,这是我的 clientInfo 。晴朗的晴天。

    现在, Swift tapStorageOut 现在是 UnsafeMutablePointer ,无论那是什么。我对如何处理它一无所知。

  3. Objective-C 处理数据时,我有一个 bufferListInOut 变量,它是指向 AudioBufferList 结构的指针。 在 Swift 中,它有 UnsafeMutablePointer 类型。所以,再一次,不了解UnsafeMutablePointers的工作原理会阻止我抓取数据。

1 个答案:

答案 0 :(得分:0)

Swift中指针的主要用途是使用C API等。在大多数情况下,你应该使用引用语义而不是Swift中的指针。这意味着使用class,当您传递class实例时,它会自动传递引用而不是制作副本。因此,它节省了资源,并且您对实例的引用所做的任何更改都会反映在引用的任何位置。 Swift类通常在堆上实例化。

当您将Objective-C转换为Swift时,指针通常被视为对这些对象的引用。在内部,Swift引用几乎是指针的语义糖。

另一方面,Swift结构具有值语义。它们通常在堆栈上实例化,当你传递它们时,它们被复制而不是传递引用。当你改变它们时会发生同样的情况,使用新值创建一个新实例,并将其替换为旧实例。有一些技巧,struct将包装一块内存并保存指向该内存的指针。因此,struct可能在内部具有一些引用语义,但试图避免在传递struct值时将其复制的期望。

一些好的阅读:

在尝试使用UnsafeMutablePointer之类的内容之前,我会先阅读这些内容并仔细查看您的体系结构。是的,它们在某些情况下很有用,但是对于大多数纯粹的Swift任务来说,它们可能会很麻烦,并且不是必需的。特别是在Swift API中!