07-Swift類和結(jié)構(gòu)體(Classes and Structures)

結(jié)構(gòu)體是構(gòu)建代碼所用的一種通用的構(gòu)造體。都是可以使用完全相同的語法規(guī)則為類和結(jié)構(gòu)體定義屬性(常量期犬、變量)河哑、添加方法,從而擴展類和結(jié)構(gòu)體的功能龟虎。

注意: 通常一個的實例稱之為對象璃谨。但在swift中,類和結(jié)構(gòu)體的關(guān)系要比在其他語言中更加的密切鲤妥。為此佳吞,更多是使用實例而不是對象。

類和結(jié)構(gòu)體的共同之處:
  • 定義屬性用于存儲值棉安;
  • 定義方法用于提供功能底扳;
  • 定義附屬腳本用于訪問值;
  • 定義構(gòu)造器用于生成初始化值垂券;
  • 通過擴展以增加默認實現(xiàn)的功能花盐;
  • 實現(xiàn)協(xié)議以提供某種標準功能;
    (注: 后續(xù)章節(jié)會講到屬性菇爪、方法算芯、下標腳本構(gòu)造過程凳宙、擴展熙揍、協(xié)議)
與結(jié)構(gòu)體相比,類附加以下功能:
  • 一個類允許繼承另外一個雷的特征氏涩;
  • 類型轉(zhuǎn)換允許在運行時檢查和解釋一個類實例的類型届囚;
  • 析構(gòu)器允許一個類實例釋放任何其所分配的資源;
  • 引用計數(shù)允許對一個類的多次引用是尖;

注意: 結(jié)構(gòu)體總是通過復(fù)制的方式在代碼中傳遞意系,不適用引用計數(shù)。


一饺汹、類和結(jié)構(gòu)體基本使用


  • 定義語法蛔添。類和結(jié)構(gòu)體定義方式類似,通過關(guān)鍵字class表示類,通過關(guān)鍵字struct表示結(jié)構(gòu)體迎瞧,并在大括號中定義具體內(nèi)容:
// 貓的類
class CatClass {
    // 名字屬性夸溶,可選類型
    var name:String?  
    // 顏色屬性
    var color:UIColor?
}
// 屏幕的結(jié)構(gòu)體
struct Screen {
    // 屏幕寬度屬性
    var w = 0
    // 屏幕高度屬性
    var h = 0
}
  • 類和結(jié)構(gòu)體的實例,類和結(jié)構(gòu)體實例類似凶硅。結(jié)構(gòu)體和類都使用構(gòu)造器語法來生成新的實例缝裁,構(gòu)造器語法的最簡單方式是在類或結(jié)構(gòu)體類型名后面跟隨一對空括號即可,而這種方式創(chuàng)建的類或結(jié)構(gòu)體實例足绅,其屬性都會初始化為默認值:
// 類的實例
let xiaomiao = CatClass()
// 結(jié)構(gòu)體的實例
var myScreen = Screen()
  • 屬性訪問捷绑,使用點語法。規(guī)則是编检,實例名后面跟隨屬性名胎食,兩者通過點.連接:
// 類實例
let xiaomiao = CatClass()
xiaomiao.name = "xiaomiao"
xiaomiao.color = UIColor.whiteColor()
// 結(jié)構(gòu)體實例
var myScreen = Screen();
myScreen.w = 320
myScreen.h = 568
  • 結(jié)構(gòu)體類型的成員逐一構(gòu)造器,所有結(jié)構(gòu)體都有一個自動生成的成員逐一構(gòu)造器允懂,用于初始化結(jié)構(gòu)體實例中的成員屬性:
var myScreen = Screen(w:320, h:400);

注: 與結(jié)構(gòu)體不同厕怜,類實例沒有默認的成員逐一構(gòu)造器。


二蕾总、結(jié)構(gòu)體和枚舉是值類型


值類型被賦予給一個變量粥航、常量或者被傳遞給一個函數(shù)時,其值會被拷貝生百。在swift中递雀,所有的基本類型:整形、浮點數(shù)蚀浆、布爾值缀程、字符串、數(shù)組市俊、字典杨凑,都是屬于值類型,并且在底層都是以結(jié)構(gòu)體的形式實現(xiàn)摆昧。
?在swift中撩满,所有的結(jié)構(gòu)體和枚舉類型都是值類型,意味著它們的實例绅你,以及實例中所包含的任何類型屬性伺帘,在代碼中傳遞的時候都會被復(fù)制。

// 屏幕結(jié)構(gòu)體
struct Screen {
    var w = 0
    var h = 0
}
// 實例結(jié)構(gòu)體
var myScreen1 = Screen(w:320, h:568);
// 賦值忌锯,結(jié)構(gòu)體是值傳遞類型伪嫁,即復(fù)制一份
var myScreen2 = myScreen1;
// 修改myScreen2,但myScreen1中是沒有任何影響的
myScreen2.h = 400;
// 實際myScreen1和myScreen2都是完全不同的實例
輸出結(jié)果:
print("myScreen1 --- w:\(myScreen1.w)  h:\(myScreen1.h)");
print("myScreen2 --- w:\(myScreen2.w)  h:\(myScreen2.h)");


三偶垮、類是引用類型


值類型不同张咳,引用類型在賦予到一個變量驹吮、常量或被傳遞到一個函數(shù)時,其值不會被拷貝晶伦。因為引用操作的都是已存在的實例本身。

// 定義貓類
class CatClass {
    var name:String?
    var color:UIColor?
}
// 貓咪多多
let duoduo = CatClass();
duoduo.name = "多多";
duoduo.color = UIColor.whiteColor();
// 賦值啄枕,cat其實表示就是duoduo這個對象本身
let cat = duoduo;
// 修改名字
cat.name = "貓星人-多多";
print("duoduo名字:\(duoduo.name)");
print("cat名字:\(cat.name)");
輸出結(jié)果:
duoduo名字:貓星人-多多
cat名字:貓星人-多多

類是引用類型婚陪,所以在上面例子中duoduocat是引用同一個CatClass實例,即是同一個實例频祝,不同名字泌参。
另外,聲明的時候使用let常空,依舊可以改變cat.name沽一。因為duoduocat這兩個常量的值為改變,只是改變它們引用實例中的name屬性而已漓糙。

  • 等價于(===)和不等價于(!==)铣缠,當(dāng)你要判斷兩個常量或者變量是否引用同一個類實例的時候進行使用:
// 判斷duoduo和cat是否引用同一個實例
if duo duo === cat {
  print("引用的是同一個實例");
}

注意: 等價于(用三個等號表示===)與等于(用兩個等號表示==)不同:
"等價于"表示兩個類型的常量或變量引用同一個類實例;
"等于"表示兩個實例的值"相等"或"相同"昆禽;


四蝗蛙、類和結(jié)構(gòu)體的選擇


類和結(jié)構(gòu)體都可以用來自定義數(shù)據(jù)類型,但結(jié)構(gòu)體實例總是通過值傳遞醉鳖,類實例總是通過引用傳遞捡硅。
?考慮使用結(jié)構(gòu)體:

  1. 該數(shù)據(jù)結(jié)構(gòu)的主要目的是用來封裝少量相關(guān)簡單數(shù)據(jù);
  2. 預(yù)計該數(shù)據(jù)結(jié)構(gòu)的實例在賦值或傳遞時盗棵,封裝的數(shù)據(jù)將會被拷貝而不是被引用壮韭;
  • 該數(shù)據(jù)結(jié)構(gòu)中存儲的值類型,也應(yīng)該被拷貝纹因,而不是被引用喷屋;
  • 該數(shù)據(jù)結(jié)構(gòu)體不需要去繼承另一個既有類型的屬性或行為;

其他情況下辐怕,定義一個類逼蒙,生成一個它的實例,并通過引用來管理和傳遞寄疏。實際中是牢,意味著絕大部分的自定義數(shù)據(jù)構(gòu)造都應(yīng)該是內(nèi),而不是結(jié)構(gòu)體陕截。


五驳棱、字符串、數(shù)組农曲、字典類型的賦值與復(fù)制行為


在swift中社搅,許多基本類型驻债,例如String、Array形葬、Dictionary類型都是以結(jié)構(gòu)體的形式實現(xiàn)合呐。即意味著被賦值或作為參數(shù)傳遞時,它們的值會被拷貝笙以。
?Objective-C中NSString淌实、NSArray、NSDictionaty類型都是類的形式實現(xiàn)猖腕,而不是結(jié)構(gòu)體拆祈。即意味著被賦值或作為參數(shù)傳遞時,不會發(fā)生值拷貝倘感,而是傳遞現(xiàn)有實例的引用放坏。

注意: 以上是字符串、數(shù)組老玛、字典的"拷貝"行為的淤年,即是拷貝行為看似總會發(fā)生。但swift中逻炊,指在絕對必要時才執(zhí)行實際的拷貝互亮。swift管理所有的值拷貝確保性能最優(yōu)化,所以我們不必去回避賦值來確保性能最優(yōu)化余素。


注:xcode7.3環(huán)境

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末豹休,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子桨吊,更是在濱河造成了極大的恐慌威根,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件视乐,死亡現(xiàn)場離奇詭異洛搀,居然都是意外死亡,警方通過查閱死者的電腦和手機佑淀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進店門留美,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人伸刃,你說我怎么就攤上這事谎砾。” “怎么了捧颅?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵景图,是天一觀的道長。 經(jīng)常有香客問我碉哑,道長挚币,這世上最難降的妖魔是什么亮蒋? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮妆毕,結(jié)果婚禮上慎玖,老公的妹妹穿的比我還像新娘。我一直安慰自己笛粘,他們只是感情好凄吏,可當(dāng)我...
    茶點故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著闰蛔,像睡著了一般。 火紅的嫁衣襯著肌膚如雪图柏。 梳的紋絲不亂的頭發(fā)上序六,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天,我揣著相機與錄音蚤吹,去河邊找鬼例诀。 笑死,一個胖子當(dāng)著我的面吹牛裁着,可吹牛的內(nèi)容都是我干的繁涂。 我是一名探鬼主播,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼二驰,長吁一口氣:“原來是場噩夢啊……” “哼扔罪!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起桶雀,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤矿酵,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后矗积,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體全肮,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年棘捣,在試婚紗的時候發(fā)現(xiàn)自己被綠了辜腺。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡乍恐,死狀恐怖评疗,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情禁熏,我是刑警寧澤壤巷,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站瞧毙,受9級特大地震影響胧华,放射性物質(zhì)發(fā)生泄漏寄症。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一矩动、第九天 我趴在偏房一處隱蔽的房頂上張望有巧。 院中可真熱鬧,春花似錦悲没、人聲如沸篮迎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽甜橱。三九已至,卻和暖如春栈戳,著一層夾襖步出監(jiān)牢的瞬間岂傲,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工子檀, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留镊掖,地道東北人。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓褂痰,卻偏偏與公主長得像亩进,于是被迫代替她去往敵國和親缩歪。 傳聞我的和親對象是個殘疾皇子归薛,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,927評論 2 355

推薦閱讀更多精彩內(nèi)容