UnsafePoint 指针

2019-07-03 17:03:29 浏览数 (1)

C是所有计算机语言永恒的话题,这个对于swift来说也不例外,虽然指针在swift中是尽量避免的,但是依然逃不出,虽然不能避免但是可以被降级对待---所有的指针在swift被冠以unsfae之名,下面是几个常用的

1 UnsafePoint

2 UnsafeMutablePoint

3 UnsafeRawPoint

4 UnsageMutableRawPoint

在说之前我们先看看指针

代码语言:javascript复制
func printUnsafeAddress<T>(atAddress p:UnsafePointer<T>){
    print(p.pointee)
}

我们来看看String的打印

代码语言:javascript复制
var abc = "abcdABCD"
printUnsafeAddress(atAddress: &abc)

看到需要一个&代表字符串的引用

代码语言:javascript复制
let  charArray = ["A", "B","1","2345"]
var intValues = charArray.compactMap { (value:String) -> Int? in
    return Int(value)
}
printUnsafeAddress(atAddress: intValues)

从上看出数组名是对应的指针在swift中也是成立的,同时对于变量天际&即得到一个UnsafePointer

有了初体验之后我们看看怎么初始化一个指针数据

1 UnsafePointer的初始化

代码语言:javascript复制
var cc  = 12
let unsafe = UnsafePointer(&cc)
printUnsafeAddress(atAddress: unsafe)

2 UnsafeMutablePointer初始化

此处我们将String转化为指针数据

代码语言:javascript复制
let data = str.data(using: String.Encoding.utf8)!
let dataLength = data.count * MemoryLayout<UInt8>.stride
let ptr =  UnsafeMutablePointer<UInt8>.allocate(capacity: data.count)

data.copyBytes(to: ptr, count: data.count)
defer{
    ptr.deallocate()
}

printUnsafeAddress(atAddress: ptr)

3 UnsafeRawPointer初始化

代码语言:javascript复制
 let rawPointer = UnsafeRawPointer(ptr)
let pointer = rawPointer.assumingMemoryBound(to: CChar.self)
String.init(cString: pointer)

‍4 数组转化UnsafeRawPointer取值

代码语言:javascript复制

let cArr = NSArray(object: str)
let cObj: UnsafeRawPointer =  CFArrayGetValueAtIndex(cArr, 0)

5 强转数据

代码语言:javascript复制
let s = unsafeBitCast(cObj, to: CFString.self)

String.init(s)

6 结合实践进行String UnsafePointer转化

代码语言:javascript复制
extension String{
    
    // String 转化为 const char *
    func convertCString(usig encoding: String.Encoding = .utf8)->UnsafePointer<Int8>{
        let data = self.data(using: encoding)!
        let bytes = UnsafeMutablePointer<UInt8>.allocate(capacity: data.count)
        defer {
            bytes.deallocate()
        }
        data.copyBytes(to: bytes, count: data.count)
        return UnsafeRawPointer(bytes).assumingMemoryBound(to: CChar.self)
    }
}

extension UnsafeMutablePointer {
    
    // 用于C字符串对比
    public func equalUnsafePointer<T> (other:UnsafePointer<T>) ->Bool{
        let cStringValue = unsafeDowncast(self.pointee as AnyObject, to: CFString.self)
        let cOtherStringValue = unsafeDowncast(other.pointee as AnyObject, to: CFString.self)
        return cStringValue == cOtherStringValue
    }
    
    public func toString()->String   {
       let cBuffer =  UnsafeRawPointer.init(self).assumingMemoryBound(to: CChar.self)
     return   String.init(cString: cBuffer)

    }
}
extension UnsafePointer{
    public func  toValue()->String{
   let unsafeMutablePointer =  UnsafeMutablePointer(mutating: self)
        let cBuffer = UnsafeMutableRawPointer.init(unsafeMutablePointer).assumingMemoryBound(to: CChar.self)
        return String.init(cString: cBuffer)
    }
}

0 人点赞