斯威夫特:如何知道是否需要复制实例? [英] Swift: How to know if an instance needs to be copied?

查看:71
本文介绍了斯威夫特:如何知道是否需要复制实例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的每个示例中,是否需要复制blob.0text?你怎么知道的?

In each of the examples below, does blob.0 or text need to be copied? How do you know?

import SQLite3
private let static_destructor = unsafeBitCast(0, to: sqlite3_destructor_type.self)
private let transient_destructor = unsafeBitCast(-1, to: sqlite3_destructor_type.self)

示例

  1. bind_blob

func bind_blob(_ stmt: OpaquePointer, _ blob: (UnsafeRawPointer, Int32)) {
  sqlite3_bind_blob(stmt, 1, blob.0, blob.1, transient_destructor)
}

  • bind_blobs

    func bind_blobs(_ stmt: OpaquePointer, _ blobs: [(UnsafeRawPointer, Int32)]) {
      for (index, blob) in blobs.enumerated() {
        sqlite3_bind_blob(stmt, Int32(index+1), blob.0, blob.1, transient_destructor)
      }
    }
    

  • bind_text

    func bind_text(_ stmt: OpaquePointer, _ text: String) {
      sqlite3_bind_text(stmt, 1, text, -1, transient_destructor)
    }
    

  • bind_texts

    func bind_texts(_ stmt: OpaquePointer, _ texts: [String]) {
      for (index, text) in texts.enumerated() {
        sqlite3_bind_text(stmt, Int32(index+1), text, -1, transient_destructor)
      }
    }
    

  • 也就是说,在任何示例中,我都应该使用static_destructor代替transient_destructor吗?

    Ie, should I use static_destructor instead of transient_destructor in any of the examples?

    相关问题:何时使用SQLITE_TRANSIENT和SQLITE_STATIC?

    推荐答案

    bind_textbind_texts函数中,您需要使用瞬态析构函数.当您将Swift String作为const char *参数传递给C函数时,Swift不保证在C函数返回后指针将保持有效. 使用指针参数调用函数文章说:

    In your bind_text and bind_texts functions, you need to use the transient destructor. When you pass a Swift String to a C function as a const char * argument, Swift does not guarantee that the pointer will remain valid after the C function returns. The Calling Functions With Pointer Parameters article says this:

    仅保证在函数调用期间传递给函数的指针有效.函数返回后,请不要保留指针并访问它.

    The pointer you pass to the function is only guaranteed to be valid for the duration of the function call. Do not persist the pointer and access it after the function has returned.

    bind_blobbind_blobs函数中,它取决于UnsafeRawPointer的来源以及执行SQL语句的时间.如果您使用任何类型的Swift withUnsafeWhatever函数获取指针,则在withUnsafeWhatever函数返回后,该指针无效.例如, withUnsafeBytes(of:_:)文档表示:

    In your bind_blob and bind_blobs functions, it depends where the UnsafeRawPointer comes from and when you execute the SQL statement. If you're getting the pointer using any sort of Swift withUnsafeWhatever function, then the pointer is not valid after the withUnsafeWhatever function returns. For example, the withUnsafeBytes(of:_:) documentation says this:

    缓冲区指针参数仅在闭包执行期间有效.

    The buffer pointer argument is valid only for the duration of the closure’s execution.

    如果绑定Blob,请执行该语句,然后不再使用绑定,则可以使用静态析构函数.可以使用静态析构函数来实现:

    If you bind your blob, execute the statement, and then no longer use the binding, then you can use the static destructor. This is okay with the static destructor:

    let data: Data = ...
    data.withUnsafeBytes { rawBuffer in
        if let pointer = rawBuffer.baseAddress {
            bind_blob(statement, (pointer, rawBuffer.count))
            execute(statement)
            // No more use of statement unless the parameter is rebound.
        }
    }
    

    但是对于静态析构函数而言,这是不可行的:

    But this is not okay with the static destructor:

    let data: Data = ...
    data.withUnsafeBytes { rawBuffer in
        if let pointer = rawBuffer.baseAddress {
            bind_blob(statement, (pointer, rawBuffer.count))
        }
    }
    execute(statement)
    

    这篇关于斯威夫特:如何知道是否需要复制实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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