亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Swift > 正文

Swift中的指針操作和使用詳細(xì)介紹

2020-03-09 17:50:53
字體:
供稿:網(wǎng)友
這篇文章主要介紹了Swift中的指針操作和使用詳細(xì)介紹,Apple期望在Swift中指針能夠盡量減少登場幾率,因此在Swift中指針被映射為了一個泛型類型,并且還比較抽象,本文詳細(xì)講解了Swift中指針的相關(guān)知識,需要的朋友可以參考下
 

Apple期望在Swift中指針能夠盡量減少登場幾率,因此在Swift中指針被映射為了一個泛型類型,并且還比較抽象。這在一定程度上造成了在Swift中指針使用的困難,特別是對那些并不熟悉指針,也沒有多少指針操作經(jīng)驗(yàn)的開發(fā)者(包括我自己也是)來說,在Swift中使用指針確實(shí)是一個挑戰(zhàn)。在這篇文章里,我希望能從最基本的使用開始,總結(jié)一下在Swift中使用指針的一些常見方式和場景。這篇文章假定你至少知道指針是什么,如果對指針本身的概念不太清楚的話,可以先看看這篇五分鐘C指針教程(或者它的中文版本),應(yīng)該會很有幫助。

初步

在Swift中,指針都使用一個特殊的類型來表示,那就是UnsafePointer<T>。遵循了Cocoa的一貫不可變原則,UnsafePointer<T> 也是不可變的。當(dāng)然對應(yīng)地,它還有一個可變變體,UnsafeMutablePointer<T>。絕大部分時間里,C中的指針都會被以這兩種類型引入到Swift中:C中const修飾的指針對應(yīng)UnsafePointer(最常見的應(yīng)該就是C字符串的const char *了),而其他可變的指針則對應(yīng)UnsafeMutablePointer。除此之外,Swift中存在表示一組連續(xù)數(shù)據(jù)指針的UnsafeBufferPointer<T>,表示非完整結(jié)構(gòu)的不透明指針COpaquePointer等等。另外你可能已經(jīng)注意到了,能夠確定指向內(nèi)容的指針類型都是泛型的struct,我們可以通過這個泛型來對指針指向的類型進(jìn)行約束以提供一定安全性。

對于一個UnsafePointer<T>類型,我們可以通過memory屬性對其進(jìn)行取值,如果這個指針是可變的UnsafeMutablePointer<T> 類型,我們還可以通過memory對它進(jìn)行賦值。比如我們想要寫一個利用指針直接操作內(nèi)存的計數(shù)器的話,可以這么做:

復(fù)制代碼代碼如下:

func incrementor(ptr: UnsafeMutablePointer<Int>) {  
    ptr.memory += 1  
}  
var a = 10  
incrementor(&a)  
a  // 11  

 

這里和C的指針使用類似,我們通過在變量名前面加上&符號就可以將指向這個變量的指針傳遞到接受指針作為參數(shù)的方法中去。在上面的incrementor中我們通過直接操作memory屬性改變了指針指向的內(nèi)容。

與這種做法類似的是使用Swift的inout關(guān)鍵字。我們在將變量傳入inout參數(shù)的函數(shù)時,同樣也使用&符號表示地址。不過區(qū)別是在函數(shù)體內(nèi)部我們不需要處理指針類型,而是可以對參數(shù)直接進(jìn)行操作。

 

復(fù)制代碼代碼如下:

func incrementor1(inout num: Int) {  
    num += 1  
}  
var b = 10  
incrementor1(&b)  
b  // 11  

 

雖然&在參數(shù)傳遞時表示的意義和C中一樣,是某個“變量的地址”,但是在Swift中我們沒有辦法直接通過這個符號獲取一個UnsafePointer的實(shí)例。需要注意這一點(diǎn)和C有所不同:

 

復(fù)制代碼代碼如下:

// 無法編譯  
let a = 100  
let b = &a  

 

指針初始化和內(nèi)存管理

在Swift中不能直接取到現(xiàn)有對象的地址,我們還是可以創(chuàng)建新的UnsafeMutablePointer對象。與Swift 中其他對象的自動內(nèi)存管理不同,對于指針的管理,是需要我們手動進(jìn)行內(nèi)存的申請和釋放的。一個 UnsafeMutablePointer的內(nèi)存有三種可能狀態(tài):

1.內(nèi)存沒有被分配,這意味著這是一個 null 指針,或者是之前已經(jīng)釋放過;
2.內(nèi)存進(jìn)行了分配,但是值還沒有被初始化;
3.內(nèi)存進(jìn)行了分配,并且值已經(jīng)被初始化。

其中只有第三種狀態(tài)下的指針是可以保證正常使用的。UnsafeMutablePointer的初始化方法(init)完成的都是從其他類型轉(zhuǎn)換到UnsafeMutablePointer的工作。我們?nèi)绻胍陆ㄒ粋€指針,需要做的是使用alloc:這個類方法。該方法接受一個num: Int作為參數(shù),將向系統(tǒng)申請num個數(shù)的對應(yīng)泛型類型的內(nèi)存。下面的代碼申請了一個Int大小的內(nèi)存,并返回指向這塊內(nèi)存的指針:

復(fù)制代碼代碼如下:

var intPtr = UnsafeMutablePointer<Int>.alloc(1)  
// "UnsafeMutablePointer(0x7FD3A8E00060)"  

接下來應(yīng)該做的是對這個指針的內(nèi)容進(jìn)行初始化,我們可以使用initialize:方法來完成初始化:
復(fù)制代碼代碼如下:

intPtr.initialize(10)  
// intPtr.memory 為 10  

在完成初始化后,我們就可以通過memory來操作指針指向的內(nèi)存值了。

 

在使用之后,我們最好盡快釋放指針指向的內(nèi)容和指針本身。與initialize:配對使用的destroy用來銷毀指針指向的對象,而與alloc:對應(yīng)的dealloc:用來釋放之前申請的內(nèi)存。它們都應(yīng)該被配對使用:

復(fù)制代碼代碼如下:

intPtr.destroy()  
intPtr.dealloc(1)  
intPtr = nil  

 

注意:其實(shí)在這里對于Int這樣的在C中映射為int的“平凡值”來說,destroy并不是必要的,因?yàn)檫@些值被分配在常量段上。但是對于像類的對象或者結(jié)構(gòu)體實(shí)例來說,如果不保證初始化和摧毀配對的話,是會出現(xiàn)內(nèi)存泄露的。所以沒有特殊考慮的話,不論內(nèi)存中到底是什么,保證initialize:和destroy配對會是一個好習(xí)慣。

指向數(shù)組的指針

在Swift中將一個數(shù)組作為參數(shù)傳遞到C API時,Swift已經(jīng)幫助我們完成了轉(zhuǎn)換,這在Apple的官方博客中有個很好的例子:

 

復(fù)制代碼代碼如下:

import Accelerate  
let a: [Float] = [1, 2, 3, 4]  
let b: [Float] = [0.5, 0.25, 0.125, 0.0625]  
var result: [Float] = [0, 0, 0, 0]  
vDSP_vadd(a, 1, b, 1, &result, 1, 4)  
// result now contains [1.5, 2.25, 3.125, 4.0625]  

 

對于一般的接受const數(shù)組的C API,其要求的類型為UnsafePointer,而非const的數(shù)組則對應(yīng)UnsafeMutablePointer。使用時,對于const的參數(shù),我們直接將Swift數(shù)組傳入(上例中的a和b);而對于可變的數(shù)組,在前面加上&后傳入即可(上例中的result)。

對于傳參,Swift進(jìn)行了簡化,使用起來非常方便。但是如果我們想要使用指針來像之前用memory的方式直接操作數(shù)組的話,就需要借助一個特殊的類型:UnsafeMutableBufferPointer。

Buffer Pointer是一段連續(xù)的內(nèi)存的指針,通常用來表達(dá)像是數(shù)組或者字典這樣的集合類型。

 

復(fù)制代碼代碼如下:

var array = [1, 2, 3, 4, 5]  
var arrayPtr = UnsafeMutableBufferPointer<Int>(start: &array, count: array.count)  
// baseAddress 是第一個元素的指針  
var basePtr = arrayPtr.baseAddress as UnsafeMutablePointer<Int>  
basePtr.memory // 1  
basePtr.memory = 10  
basePtr.memory // 10  
//下一個元素  
var nextPtr = basePtr.successor()  
nextPtr.memory // 2  

 

指針操作和轉(zhuǎn)換

withUnsafePointer

上面我們說過,在Swift中不能像C里那樣使用&符號直接獲取地址來進(jìn)行操作。如果我們想對某個變量進(jìn)行指針操作,我們可以借助withUnsafePointer這個輔助方法。這個方法接受兩個參數(shù),第一個是 inout的任意類型,第二個是一個閉包。Swift會將第一個輸入轉(zhuǎn)換為指針,然后將這個轉(zhuǎn)換后的Unsafe的指針作為參數(shù),去調(diào)用閉包。使用起來大概是這個樣子:

復(fù)制代碼代碼如下:

var test = 10  
test = withUnsafeMutablePointer(&test, { (ptr: UnsafeMutablePointer<Int>) -> Int in  
    ptr.memory += 1  
    return ptr.memory  
})  
test // 11  

這里其實(shí)我們做了和文章一開始的incrementor相同的事情,區(qū)別在于不需要通過方法的調(diào)用來將值轉(zhuǎn)換為指針。這么做的好處對于那些只會執(zhí)行一次的指針操作來說是顯而易見的,可以將“我們就是想對這個指針做點(diǎn)事兒”這個意圖表達(dá)得更加清晰明確。

 

unsafeBitCast

unsafeBitCast是非常危險的操作,它會將一個指針指向的內(nèi)存強(qiáng)制按位轉(zhuǎn)換為目標(biāo)的類型。因?yàn)檫@種轉(zhuǎn)換是在Swift的類型管理之外進(jìn)行的,因此編譯器無法確保得到的類型是否確實(shí)正確,你必須明確地知道你在做什么。比如:

復(fù)制代碼代碼如下:

let arr = NSArray(object: "meow")  
let str = unsafeBitCast(CFArrayGetValueAtIndex(arr, 0), CFString.self)  
str // “meow”  

因?yàn)镹SArray是可以存放任意NSObject對象的,當(dāng)我們在使用CFArrayGetValueAtIndex從中取值的時候,得到的結(jié)果將是一個UnsafePointer<Void>。由于我們很明白其中存放的是String對象,因此可以直接將其強(qiáng)制轉(zhuǎn)換為CFString。

 

關(guān)于unsafeBitCast一種更常見的使用場景是不同類型的指針之間進(jìn)行轉(zhuǎn)換。因?yàn)橹羔槺旧硭加玫牡拇笮∈且欢ǖ?,所以指針的類型進(jìn)行轉(zhuǎn)換是不會出什么致命問題的。這在與一些C API協(xié)作時會很常見。比如有很多C API要求的輸入是void *,對應(yīng)到Swift中為UnsafePointer<Void>。我們可以通過下面這樣的方式將任意指針轉(zhuǎn)換為UnsafePointer。

復(fù)制代碼代碼如下:

var count = 100  
var voidPtr = withUnsafePointer(&count, { (a: UnsafePointer<Int>) -> UnsafePointer<Void> in  
    return unsafeBitCast(a, UnsafePointer<Void>.self)  
})  
// voidPtr 是 UnsafePointer<Void>。相當(dāng)于 C 中的 void *  
// 轉(zhuǎn)換回 UnsafePointer<Int>  
var intPtr = unsafeBitCast(voidPtr, UnsafePointer<Int>.self)  
intPtr.memory //100  

 

總結(jié)

Swift從設(shè)計上來說就是以安全作為重要原則的,雖然可能有些啰嗦,但是還是要重申在Swift中直接使用和操作指針應(yīng)該作為最后的手段,它們始終是無法確保安全的。從傳統(tǒng)的C代碼和與之無縫配合的Objective-C代碼遷移到Swift并不是一件小工程,我們的代碼庫肯定會時不時出現(xiàn)一些和C協(xié)作的地方。我們當(dāng)然可以選擇使用Swift重寫部分陳舊代碼,但是對于像是安全或者性能至關(guān)重要的部分,我們可能除了繼續(xù)使用C API以外別無選擇。如果我們想要繼續(xù)使用那些API的話,了解一些基本的Swift指針操作和使用的知識會很有幫助。

對于新的代碼,盡量避免使用Unsafe開頭的類型,意味著可以避免很多不必要的麻煩。Swift給開發(fā)者帶來的最大好處是可以讓我們用更加先進(jìn)的編程思想,進(jìn)行更快和更專注的開發(fā)。只有在尊重這種思想的前提下,我們才能更好地享受這門新語言帶來的種種優(yōu)勢。顯然,這種思想是不包括到處使用 UnsafePointer的。



注:相關(guān)教程知識閱讀請移步到swift教程頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
欧美日韩国产精品一区二区亚洲| 偷拍自拍在线| 亚洲制服欧美另类| 成人黄色a**站在线观看| 我要看黄色一级片| 国产日韩欧美久久| 青青草在线播放| 老司机福利在线观看| 欧美色欧美亚洲高清在线视频| 色婷婷综合网站| 女人扒开屁股爽桶30分钟| 高清日韩欧美| 国产成人综合在线| 日本免费色视频| 成人黄色在线视频| 免费91麻豆精品国产自产在线观看| 成人黄色在线| 久久亚洲精精品中文字幕早川悠里| 一级毛片国产| 少妇无码一区二区三区| 一本大道av伊人久久综合| 韩国成人免费视频| 精彩视频一区二区三区| 欧美夫妻性生活视频| 日本道免费精品一区二区三区| 日韩综合一区二区| 日韩精品视频免费播放| 337p日本欧洲亚洲大胆色噜噜| 色综合久久综合中文综合网| 欧美午夜激情小视频| 成人午夜免费av| aaa亚洲精品| 奇米影视888狠狠狠777不卡| 日韩亚洲欧美中文在线| 日韩欧美在线观看一区二区| 91精品国产乱码久久久| аⅴ资源新版在线天堂| 久久久www免费人成黑人精品| 青青草免费观看完整版高清| 6080日韩午夜伦伦午夜伦| 久久麻豆视频| 亚洲欧洲国产伦综合| 啪啪免费网站| 日日夜夜操操操| 日韩在线视频中文字幕| 亚洲18在线看污www麻豆| 91精品国产综合久久婷婷香蕉| 精品处破女学生| 国产综合色精品一区二区三区| 久久电影网站| 日本护士做爰视频| 俺去啦俺在线观看| www99热| 韩国午夜理伦三级不卡影院| 国内精品免费午夜毛片| 日本 国产 欧美色综合| 国产午夜三级一区二区三| 国产精品美女一区二区视频| 天堂国产一区二区三区| 无码人妻精品一区二区中文| 欧产日产国产69| 2020国产精品小视频| 欧美吻胸吃奶大尺度电影| 久久99精品国产麻豆不卡| 噜噜噜久久亚洲精品国产品小说| 99精品视频网| 日韩午夜免费视频| 欧美性猛交乱大交| 最新在线观看av| 免费黄网站在线观看| 国产精品亚洲欧美| 污网站在线观看视频| 国产视频一区二区不卡| 91亚洲精品在看在线观看高清| 日韩精品欧美激情一区二区| 小泽玛利亚视频在线观看| 久久天天躁狠狠躁夜夜爽蜜月| 少妇人妻好深好紧精品无码| 懂色av一区| 国产午夜福利100集发布| 日本少妇一区二区| 国产欧美日本| 91国语精品自产拍在线观看性色| 国产免费一区视频观看免费| 成人av激情人伦小说| 屁屁影院国产第一页| 日本成在线观看| 日本老师69xxx| 成人羞羞网站入口免费| 亚洲成人一区| 国产精品国产三级国产专区52| 日韩美女在线| 亚洲区一区二区三| 91免费看视频| 欧美特级特黄aaaaaa在线看| 台湾佬中文在线| 欧美日韩国产一区二区三区| 影音先锋男人在线资源| 久久资源中文字幕| 国产精品综合久久久久久| 久久久久免费| 国产肥白大熟妇bbbb视频| 亚洲美女久久久| 久久影院免费观看| 最近2019中文字幕在线高清| 免费在线a视频| 久久欧美在线电影| 精品人妻少妇嫩草av无码专区| 国产精品不卡一区二区三区在线观看| 天天爽夜夜爽| 国产一级片视频| heyzo高清在线| av网在线观看| 丰满的少妇愉情hd高清果冻传媒| 日韩少妇与小伙激情| 国产日本一区二区| 日韩视频在线观看一区二区| 久久精品一区蜜桃臀影院| 老女人av在线| 久久九九影视网| 亚洲国产精品激情在线观看| 欧美一区二区三区不卡视频| 成**人特级毛片www免费| 午夜精品短视频| 久久精品亚洲乱码伦伦中文| 欧美性一二三区| 久久免费国产精品1| 日韩熟女精品一区二区三区| asian性开放少妇pics| 99久久人爽人人添人人澡| 国产又色又爽又黄的| 神马久久精品综合| 久久国产精品亚洲va麻豆| 精品美女在线观看视频在线观看| 亚洲色图综合久久| 一区二区三区视频网| 中文字幕亚洲欧美| 桃乃木香奈av在线| 久久久久久久一| xxxxhd欧美精品| 欧美成人自拍视频| 嫩草影院国产精品| 麻豆精品在线视频| 亚洲最大的免费| 国产自产女人91一区在线观看| www.成人精品免费网站青椒| 精品人妻二区中文字幕| 欧美精品与人动性物交免费看| 懂色av一区二区三区四区五区| 国产成人激情小视频| 中文字幕免费观看一区| 欧美视频在线观看免费网址| 亚洲免费一级视频| 欧美日韩国产一级二级| 久久久久久国产精品mv| 亚洲怡红院在线观看| 国产精品久久久久aaaa| 亚洲精品国产一区二区三区| 亚洲精品在线观看av| 国产精品精品一区二区三区午夜版| xxx免费视频观看| 欧美午夜精品理论片a级大开眼界| 成人做爰www看视频软件| 日本亚洲一区二区| 欧美孕妇孕交| 亚洲精品www久久久| 激情五月播播久久久精品| 在线观看a级片| 偷拍一区二区三区| 精品一区久久| 神马久久久久久| 亚洲国产aⅴ精品一区二区| 视频一区三区| 亚洲网站视频在线观看| 一区二区三区国产精华| 国产高清在线精品| 蜜桃av噜噜一区二区三区小说| 成人免费淫片95视频观看网站| 欧美人xxx| 国产情侣第一页| 日韩精品视频在线观看视频| 九9re精品视频在线观看re6| 国产在线观看精品一区二区三区| av电影一区二区三区| 国产91社区| eeuss影院18直达| 免费高清视频日韩| 日韩精品午夜视频| av在线免费观看网| 精品人妻一区二区三区四区不卡| 久久国产这里只有精品| 日韩av快播网址| 中国xxxx自拍视频| av网站免费在线观看| av成人资源网| 粉嫩蜜臀av国产精品网站| 久久亚洲电影| 97人妻精品一区二区三区免| 性做久久久久久久久| 米奇777在线欧美播放| 成人福利影院| www久久99| 日本高清不卡一区二区三区视频| 欧美13一14另类| 九九热久久免费视频| 久热在线中文字幕色999舞| 在线电影福利片| 国产精品国产三级国产aⅴ浪潮| 国产日韩成人内射视频| 欧美影院久久久| 亚洲激情国产| 色偷偷亚洲男人天堂| 欧美日本国产精品| 色se01短视频永久免费| 国产又粗又黄视频| jizz在亚洲| 色偷偷偷亚洲综合网另类| 在线宅男视频| 在线亚洲一区| 538任你躁在线精品视频网站| 91高清视频免费看| 一级黄色免费网站| 亚洲七七久久综合桃花剧情介绍| 在线看片第一页欧美| 香蕉成人啪国产精品视频综合网| 久久久久久婷| 女人av一区| 老司机午夜免费精品视频| 国产18无套直看片| 国产精品传媒毛片三区| 欧美偷拍第一页| 久久免费精品一区二区| 天堂中文а√在线| 精品视频国内| 国产成人在线亚洲欧美| 日本福利视频在线观看| 日本在线视频一区二区三区| 99久久夜色精品国产亚洲狼| 日本www视频在线观看| 欧美大片在线免费观看| 青青青伊人色综合久久| 亚亚洲欧洲精品| 久9re热视频这里只有精品| 久久本道综合色狠狠五月| 超碰porn在线| 国产精品视频第一页| 日韩丰满少妇无码内射| 成人免费黄色在线| 福利片在线观看| 欧美激情网站| 亚洲精品国产久| 91成人福利社区| 国产深夜精品| ts人妖交友网站| 中文字幕+乱码+中文字幕明步| 黑人精品欧美一区二区蜜桃| 五月婷婷久久久| 亚洲天堂电影在线观看| 成人羞羞国产免费网站| 波多野结衣一区二区在线| 你懂的网址视频| 91亚洲精华国产精华精华液| 国产一区二区色噜噜| 性色av无码久久一区二区三区| 亚洲精品第一国产综合野| 日韩精品久久久久久免费| 免费h精品视频在线播放| 亚洲欧美日本一区二区| 国产精品久久久亚洲| 日韩女同强女同hd| 蜜臀av无码一区二区三区| 麻豆精品蜜桃视频网站| 91精品视频网站| 亚洲不卡一卡2卡三卡4卡5卡精品| 乌克兰美女av| 色综合网色综合| 国产视频一二三四区| 国产私拍福利精品视频二区| 在线影院自拍| 日韩激情av在线免费观看| 六月丁香综合在线视频| 男人捅女人免费视频| 欧美激情国内自拍| 青青操免费在线视频| 国产精品视频| www.黄色网| 久久电影天堂| 奇米四色7777| 国产探花在线播放| 大桥未久av一区二区三区| 日日摸夜夜夜夜夜添| 媚黑女一区二区| 91av看片| 午夜美女久久久久爽久久| 国产日韩一区二区三区在线播放| 欧美人与性动交α欧美精品| 91久久精品日日躁夜夜躁欧美| 老司机色在线视频| 亚洲国产精品视频在线观看| 日本毛片在线观看| 免费一级片网址| 91精品91久久久中77777老牛| 黄大色黄女片18免费| 人人爽香蕉精品| 中文字幕日韩高清在线| 九色网友自拍视频手机在线| 亚洲欧美在线网| 欧美三级日本三级少妇99| 国产精品久久久久高潮| 日韩视频免费直播| 国产一线二线在线观看| 国产91精品高潮白浆喷水| 日韩不卡一区二区| 亚洲电影先锋| 伊甸园亚洲一区| 中国毛片在线观看| 网友自拍区视频精品| 日韩手机在线导航| 91这里只有精品| 一个人看的www在线免费视频| 国产激情在线看| 成人精品一区二区三区电影黑人| jizz免费视频| 极品av少妇一区二区| 日韩黄色碟片| 国产精品伊人| 1024手机在线观看你懂的| 欧美不卡三区|