【问题标题】:'init' is unavailable: use 'withMemoryRebound(to:Capacity:_)' UnsafeMutablePointer'init' 不可用:使用 'withMemoryRebound(to:Capacity:_)' UnsafeMutablePointer
【发布时间】:2019-01-15 13:28:31
【问题描述】:

我想在 Swift 3 和 4 中使用这个 Swift 2 代码:

func getLocalIP() -> String {
    var address = "error"
    var interfaces : UnsafeMutablePointer<ifaddrs>? = nil
    var temp_addr : UnsafeMutablePointer<ifaddrs>? = nil
    var success : Int32 = 0
    // Retrieve the current interfaces - returns 0 on success.
    success = getifaddrs(&interfaces)
    if success == 0 {
        // Loop through linked list of interfaces.
        temp_addr = interfaces
        while temp_addr != nil {
            if temp_addr?.pointee.ifa_addr.pointee.sa_family == UInt8(AF_INET) {
                // Check if interface is en0 which is the wifi connection on the iPhone.
                if String(cString: (temp_addr?.pointee.ifa_name)!) == "en0" {
                    // Get NSString from C string.
                    address = String(cString: inet_ntoa(UnsafeMutablePointer<sockaddr_in>((temp_addr?.pointee.ifa_addr)!).pointee.sin_addr))
                }
            }
            temp_addr = temp_addr?.pointee.ifa_next
        }
    }
    // Free memory.
    freeifaddrs(interfaces)
    return address
}

UnsafeMutablePointer 出现错误:

'init' 不可用:使用'withMemoryRebound(to:Capacity:_)'

【问题讨论】:

    标签: swift3 swift2 task swift4 info


    【解决方案1】:

    错误文本准确地说明了问题所在以及您应该做什么:您不能再使用指向另一种类型的指针来创建UnsafeMutablePointer,而必须使用.withMemoryRebound(to:Capacity:_) 方法。

    在你的情况下,你应该替换

    String(cString: inet_ntoa(UnsafeMutablePointer<sockaddr_in>((temp_addr?.pointee.ifa_addr)!).pointee.sin_addr))
    

    类似的东西:

    temp_addr.pointee.ifa_addr.withMemoryRebound(to: sockaddr_in.self, capacity: 1, { sockaddr_ptr -> String? in
       guard let sin_addr = inet_ntoa(sockaddr_ptr.pointee.sin_addr) else { return nil }
       return String(cString: sin_addr)
    })
    

    或者这里是你的函数的完全重写和增强版本:

    enum LocalIPError: Error {
        case failedToRetrieveInterfaces(errorCode: Int32)
        case noEn0Address
    }
    
    func getLocalIP() throws -> String {
        // Retrieve the current interfaces - returns 0 on success.
        var interfaces : UnsafeMutablePointer<ifaddrs>? = nil
        let errorCode = getifaddrs(&interfaces)
    
        defer {
            // Free memory.
            freeifaddrs(interfaces)
        }
    
        guard
            errorCode == 0,
            let interfaceSequence = interfaces.flatMap({ first_addr in
                sequence(
                    first: first_addr,
                    next: { addr in addr.pointee.ifa_next }
                )
            })
            else { throw LocalIPError.failedToRetrieveInterfaces(errorCode: errorCode) }
    
        if let address = interfaceSequence.compactMap({ (temp_addr) -> String? in
            guard
                let ifa_addr = temp_addr.pointee.ifa_addr,
                ifa_addr.pointee.sa_family == sa_family_t(AF_INET),
                // Check if interface is en0 which is the wifi connection on the iPhone.
                String(cString: (temp_addr.pointee.ifa_name)) == "en0"
                else { return nil }
    
            return ifa_addr.withMemoryRebound(to: sockaddr_in.self, capacity: 1, { sockaddr_ptr -> String? in
                guard let sin_addr = inet_ntoa(sockaddr_ptr.pointee.sin_addr) else { return nil }
                return String(cString: sin_addr)
            })
        }).last {
            return address
        } else {
            throw LocalIPError.noEn0Address
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2017-08-23
      • 1970-01-01
      • 2016-01-19
      • 1970-01-01
      • 2016-12-24
      • 2016-05-20
      • 1970-01-01
      • 2023-03-27
      • 1970-01-01
      相关资源
      最近更新 更多