第一天視頻課程:
Objective-C 語言簡介
Objective-C 語言是一門在C語言基礎(chǔ)上做了面向?qū)ο髷U展的編程語言访得,1983年由Brad Cox 和Tom Love發(fā)明龙亲,是目前蘋果開發(fā)平臺的主力語言,與Cocoa 和Cocoa Touch框架高度集成悍抑,支持開發(fā)Mac OS X鳄炉、iOS應(yīng)用。在蘋果開發(fā)平臺上通過LLVM(LowLevelVirtualMachine)編譯器架構(gòu)支持與Swift語言雙向互操作搜骡。
iOS開發(fā)平臺
Cocoa框架部分包括了系統(tǒng)內(nèi)核(Core OS)拂盯、內(nèi)核服務(wù)(Core Service)、媒體(Media)记靡、觸摸(Cocoa Touch)這幾個內(nèi)庫谈竿。通過LLVM編譯框架和Objective-C運行時編譯和運行团驱。目前主要有Objective-C、Swift和C/C++這幾種語言來進行編碼空凸,常用的開發(fā)工具為Xcode嚎花。
掌握高級編程語言的思維方式
底層思維:從微觀、機器的層面理解語言的構(gòu)造呀洲、編譯轉(zhuǎn)換紊选、內(nèi)存模型和運行時機制。
抽象思維:將我們周圍世界抽象為程序代碼道逗,即面向?qū)ο蟮乃季S方式丛楚,組件封裝、設(shè)計模式憔辫、架構(gòu)模式。
“時空人”三位一體分析方法
時間分析仿荆,發(fā)生在什么時候贰您?編譯時還是運行時。
空間分析拢操,變量放在那里锦亦?堆空間還是棧空間令境。
人物分析杠园,代碼哪里來的?程序員還是編譯器舔庶、運行時抛蚁、框架。
Objective-C 語言的兩種開發(fā)方式
Clang 或 GCC命令行:適合調(diào)試惕橙、研究瞧甩、微觀探查。
Xcode項目:適合構(gòu)建正規(guī)工程項目弥鹦,使用大型框架肚逸,追求設(shè)計質(zhì)量與代碼組織。
Objective-C 語言代碼學(xué)習(xí)
#import 導(dǎo)入頭文件(類似C語言的#include)彬坏,可以避免相同頭文件的重復(fù)導(dǎo)入朦促,推薦使用#import代替#include。
@autoreleasepool 支持ARC(Automatic Reference Counting)的一個池栓始,用來表明啟用了內(nèi)存自動回收機制务冕。
NSlog(@"Hello,world!"); NSlog類似C語言里的printf用來打印字符串,OC語言里的字符串前需要加@符號(@"Hello,world!")混滔。
?頭文件的擴展名是.h洒疚,主程序文件的擴展名是.m
編譯命名行:clang -fobjc-arc HelloWorld.m -o HelloWorld其中-fobjc-arc為ARC內(nèi)存管理的開關(guān)命名歹颓,其中-o HelloWorld,-o 為output即輸出的意思油湖,一起為將輸出的文件命名為HelloWorld巍扛。clang也可以換成gcc即用gcc編譯器編譯。(推薦用clang)
命名行:clang -help 用來顯示clang的設(shè)置幫助文檔乏德,可以用來了解clang的設(shè)置撤奸。
命名行:./HelloWorld 執(zhí)行生成的HelloWorld文件。
ObjC編譯過程
目前主流為LLVM-Clang的編譯過程喊括,由OC胧瓜、C\C++代碼通過Clang前端再通過LLVM優(yōu)化和LLVM代碼生成器生成出X86-64機器碼。
學(xué)習(xí)資源
蘋果官方文檔:https://developer.apple.com/library/
programming with Objective-C: https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/
iOS專區(qū):https://developer.apple.com/library/ios/
蘋果開發(fā)者大會WWDC:https://developer.apple.com/videos/wwdc/2014/
??????????????????????WWDC:https://developer.apple.com/videos/wwdc/2015/
第二天視頻課程:
類型系統(tǒng)
引用類型 reference type:包括class郑什、pointer府喳、block。
值類型 value type:包括基礎(chǔ)數(shù)值類型蘑拯、結(jié)構(gòu)struct钝满、枚舉enum。
類型裝飾:包括協(xié)議protocol申窘、類別category弯蚜、擴展extension
類 class VS. 結(jié)構(gòu) struct
類型與實例:類的實例是對象,結(jié)構(gòu)的實例是值剃法。
類是一個引用類型碎捺,是位于棧上的指針指向了一個位于堆上的實體對象。
結(jié)構(gòu)是一個值類型贷洲,它直接位于棧中收厨。
例子1:聲明一個類(建立一個對外接口)
@interface RPoint:NSObject? //聲明一個類,類名RPoint优构,繼承自類NSObject帽氓。:表示繼承。
@property int x; //聲明一個屬性 int X
@property int y;
-(void)print; //聲明一個實例方法 print
@end
在OC中創(chuàng)建類時要先在頭文件中(.h)創(chuàng)建一個對外借口俩块,@interface來表示對外接口的起始黎休,用@end來對應(yīng)結(jié)束。
@property 在類中定義屬性的關(guān)鍵字玉凯,用來表示這個類的狀態(tài)势腮。
-(void)print 是在類中定義方法的語句,其中-表示是一個實例方法漫仆,方法的返回值是void,方法的名字是print.類中的方法來表示這個類的行為捎拯。
例子2:實現(xiàn)一個類
#import<Foundation/Foundation.h> //導(dǎo)入Foundation.h頭文件
#import"rpoint.h" //導(dǎo)入rpoint.h頭文件,即上面我們創(chuàng)建的類聲明文件盲厌。
@implementation RPoint? //定義一個類名為RPoint?的類
-(void)print{
NSLog(@"[%d,%d]", self.x, self.y);? //print方法的實現(xiàn)
}
@end
OC的類需要在主文件中(.m)實現(xiàn)署照,@implementation 來表示實現(xiàn)的起始祸泪,用@end來對應(yīng)結(jié)束。
NSLog(@"[%d,%d]", self.x, self.y);? NSLog表示打印一個字符串建芙,self表示當(dāng)前的事例没隘,整句語句表示將當(dāng)前事例的屬性x和y打印出來。
例子3:
#import<Foundation/Foundation.h>
#import"rpoint.h" //導(dǎo)入類所在的文件
#import"spoint.h"? //導(dǎo)入結(jié)構(gòu)體所在的文件
void process(RPoint* rp3, SPoint sp3); //函數(shù)process的聲明
int main(int argc, const char * argv[]){ //入口函數(shù)
??? @autoreleasepool{
????? RPoint* rp1=[[RPoint alloc]init]; //生成一個RPoint類的對象rp1
????? rp1.x=10;
????? rp1.y=20;
????? [rp1 print]; //顯示結(jié)果為10禁荸, 20
????? SPoint sp1; //生成一個SPoint結(jié)構(gòu)體實例右蒲。
????? sp1.x=10;
????? sp2.y=20;
????? NSLog(@"拷貝----------");
????? RPoint* rp2=rp1;
????? rp2.x++;
????? rp2.y++;
????? [rp1 print]; //顯示結(jié)果為11赶熟, 21
????? [rp2 print]; //顯示結(jié)果為11瑰妄, 21
????? SPoint sp2=sp1;
????? sp2.x++;
????? sp2.y++;
????? NSLog(@"[%d,%d]",sp1.x, sp1.y);?//顯示結(jié)果為10, 20
????? NSLog(@"[%d,%d]",sp2.x, sp2.y); //顯示結(jié)果為11映砖, 21
????? NSLog(@"傳參----------")
????? process(rp1, sp1);
????? [rp1 print]; //顯示結(jié)果為12间坐, 22
????? NSLog(@"[%d,%d]",sp1.x, sp1.y); //顯示結(jié)果為10, 20
??? }
??? return0;
}
void process(RPoint* rp3, SPoint sp3){
? rp3.x++;
? rp3.y++;
? sp3.x++;
? sp3.y++;
? [rp3 print];
? NSLog(@"[%d,%d]",sp3.x, sp3.y);
}
RPoint* rp1=[[RPoint alloc] init]; //在內(nèi)存椧赝耍空間創(chuàng)建了一個名字為rp1的RPpoint類實例對象眶诈。[]為調(diào)用符號,調(diào)用也可以稱為發(fā)送消息瓜饥。alloc的用處是手動在堆空間申請內(nèi)存空間,init為初始化所分配的空間浴骂。
堆(heap):堆空間用于存儲引用類型對象乓土,由程序員手動申請內(nèi)存空間,釋放由運行時ARC機制自動釋放溯警,函數(shù)之間通過拷貝引用(指針)傳遞趣苏。堆空間具有全局性,總體大小受制于系統(tǒng)內(nèi)存整體大小梯轻。
由于rp1是一個類的實例對象食磕,所以無論是復(fù)制還是傳參,都是由一個棧中的指針指向堆中的實體對象喳挑,復(fù)制副本和傳參參數(shù)的改變都能直接導(dǎo)致rp1指向的實際對象發(fā)生改變彬伦。
SPoint sp1; //在內(nèi)存的堆空間創(chuàng)建了一個名字為sp1的結(jié)構(gòu)體。
棧(stack):椧了校空間用于存儲值類型单绑,無ARC負擔(dān),由系統(tǒng)自動管理曹宴,以執(zhí)行函數(shù)為單位搂橙。棧的空間大小在編譯時確定(根據(jù)參數(shù)+局部變量來計算),在函數(shù)執(zhí)行時由系統(tǒng)自動分配一個棧笛坦,函數(shù)執(zhí)行結(jié)束系統(tǒng)立即自動收回該椙空間苔巨,函數(shù)之間通過拷貝值傳遞。椃侠耄空間具有局部性侄泽,大小有限額(編譯工具可以設(shè)定棧的大小,一般為1M)厅缺,超出會棧溢出(stack overflow)蔬顾。
由于sp1是一個結(jié)構(gòu)值,它存儲于棧中湘捎,無論復(fù)制還是傳參诀豁,都將在棧中復(fù)制一個sp1的副本,sp1的原始值保持不變窥妇。
第三天視頻課程:
OC類的類型成員
OC類所包含的類型成員(Type Member)主要分為兩大類舷胜,一類是數(shù)據(jù)成員(data member)用來描述對象的狀態(tài),還有一類是函數(shù)成員(function member)用來描述對象的行為活翩。其中數(shù)據(jù)成員又有實例變量(instance variable)和屬性(property)兩種烹骨。函數(shù)成員分為方法(method)、初始化器(init)和析構(gòu)器(dealloc)三種材泄。
認識屬性
屬性表達實例狀態(tài)沮焕,描述類型對外接口。相比直接訪問實例變量拉宗,屬性可以做更多控制峦树。
默認情況下,編譯器會為屬性定義propertyName自動合成一個getter訪問器方法:propertyName旦事、一個setter訪問器方法:setPropertyName還有一個實例變量_propertyName魁巩。
舉例:
在OC類中聲明一個屬性:@property NSString* firstName; //聲明一個類所包含的屬性。
此時編譯器會自動生成類似如下代碼姐浮,但是并不顯示出來:
-(NSString*)firstName{? //生成一個getter函數(shù)
???return _firstName;
}
-(void)setFirstName:(NSString *)newValue{? //生成一個setter函數(shù)
??_firstName=newValue;
}
NSString* _firstName; //創(chuàng)建一個以 _(下劃線)+屬性名的實例變量
由于編譯器自動生成了類似如上代碼谷遂,我們可以用編譯器生成的getter方法和setter方法來訪問或修改該屬性的內(nèi)容。
例如:
Employee* employee=[[Employee alloc] init];
[employee setFirstName: @"Tom"]; //將employee類的FirstName屬性設(shè)置為“Tom”卖鲤,setFirstName這個setter方法是編譯器自動生成的肾扰。
NSLog(@"First Name: %@", [employee firstName]); //打印出employee類的FirstName屬性,此處[employee firstName]是調(diào)用了編譯器自動生成的getter方法firstName蛋逾。
除了以上的方法來訪問getter和setter方法外白对,可以用類名+.(點表達式)+屬性名來訪問屬性的getter和setter方法。
例如:
employee.lastName=@"Chen"; //訪問了lastName屬性的setter表達式,等價于[employee setFirstName: @"Chen"];
NSLog(@"First Name: %@", employee.lastName); //訪問了lastName屬性的getter表達式换怖,等價于NSLog(@"First Name: %@", [employee firstName]);
兩種方法在本質(zhì)上沒有什么區(qū)別甩恼,推薦用點表達式,使用比較方便。
可自定義訪問器方法条摸,也可更改訪問器方法名或?qū)嵗兞棵?/strong>
例如:
@property (readonly) NSString* fullName; //在頭文件中定義了一個只讀屬性fullName
-(NSString *)fullName{
? return [NSString stringWithFormat:@"%@ %@", self.firstName, self.lastName];
} //在主文件中自定義了fullName屬性的getter訪問器方法悦污。stringWithFormat函數(shù)是用來鏈接兩個字符串類實例。
@property (getter=GivenName, setter=GivenName:) NSString* firstName; //聲明firstName屬性時將該屬性的getter钉蒲、setter訪問器的名字都設(shè)置為GivenName切端。
@synthesize firstName=givenName; //在主文件中將firstName屬性由系統(tǒng)自動生成的_firstName實例變量改名為givenName。
可以使用靜態(tài)全局變量(C語言)+類方法顷啼,模擬類型屬性踏枣。
static int _max=100; //在主文件中定義一個靜態(tài)變量_max
+(int)max; //在頭文件中聲明一個類方法(getter訪問器) +(int)max
+(void)setMax:(int)newValue; //在頭文件中聲明一個類方法(setter訪問器)? +(void)setMax
+(int)max{
return _max;? //在主文件中實現(xiàn)類方法+(int)max
}
+(void)setMax:(int)newValue{
????? _max=newValue;? //在主文件中實現(xiàn)類方法+(void)setMax
}
完成以上步驟后,可以實現(xiàn)訪問類型屬性钙蒙。
[Employee setMax:400]; 等同于Employee.max=400; 模擬出來的類屬性茵瀑。
實例變量
可以定義實例變量,而不定義屬性(這樣外部不能訪問到實例變量)躬厌,只有實例變量马昨,沒有類變量(使用靜態(tài)全局變量+類方法可以模擬出類變量的效果)。
如果同時自定義了getter和setter訪問器方法扛施,或者針對只讀屬性定義了getter訪問器方法鸿捧,編譯器將不再合成實例變量。
引用類型的實例變量在類外一律使用屬性來訪問疙渣,類內(nèi)大多也通過self使用屬性訪問匙奴。只有以下情就卡了況使用實例變量來訪問:1、初始化器 init? 2妄荔、析構(gòu)器 dealloc 3泼菌、自定義訪問器方法。?
實例變量的生存周期
實例變量的儲存:跟隨對象實例存儲在堆上懦冰。
值類型實例變量直接“內(nèi)嵌”在對象實例中。跟隨對象實例內(nèi)存釋放而被釋放谣沸。
引用類型實例變量通過指針“引用”堆上的引用類型實例刷钢,ARC針對引用進行計數(shù)管理,自動釋放引用計數(shù)為0的對象乳附。
屬性的描述特性(Attribute)
屬性的描述特性可以指定屬性不同環(huán)境下的不同功能内地。
讀寫特性,默認情況屬性都是可讀寫(readwrite)的赋除,也可以設(shè)置為只讀(readonly)屬性阱缓。
例如:
@property (readonly) NSString* fullName; //在頭文件中定義了一個只讀屬性fullName
多線程特性,默認情況下是屬性是原子性(atomic)的举农,表示多線程時原子性屬性不能被線程搶走荆针,要么沒有運行,開始運行了必須運行到結(jié)束。也可以設(shè)置為非原子性(nonatomic).
例如:
@property (nonatomic) NSString* fullName; //在頭文件中定義了一個非原子性屬性fullName
內(nèi)存管理特性
引用屬性默認為強(strong)引用屬性航背,弱(weak)引用阻止循環(huán)引用喉悴。當(dāng)兩個實例對象屬性相互強引用時會形成循環(huán)引用,這時ARC內(nèi)存管理將視這兩個互引用的屬性都占用玖媚,無法將這兩個實例的引用屬性釋放箕肃。
為了避免上述情況發(fā)生把其中一個對象屬性設(shè)置為弱引用今魔,這樣就不會出現(xiàn)不能釋放的問題了勺像。
拷貝(copy)屬性創(chuàng)建獨立拷貝错森,當(dāng)引用屬性不想被外界直接引用時吟宦,可以用拷貝屬性,讓外界引用一個拷貝副本问词,來確保原始數(shù)據(jù)不會被外界修改督函。
第四天視頻課程:
認識方法 Method
代碼段上的可執(zhí)行指令序列就是函數(shù)辰狡,函數(shù)有全局函數(shù)(C語言函數(shù)),和成員函數(shù)(OC中也叫方法)垄分。
方法是類的成員函數(shù)宛篇,表達實例行為或類型行為。
舉例:
以下聲明了4個方法
-(void) print; //-表示是實例方法薄湿,返回值是void, 方法名是print, 無參數(shù)
-(BOOL) isEqualToPoint: (BLNPoint*) point; //返回值是BOOL, 參數(shù)名是point, 參數(shù)類型是BLNPoint*
-(void) moveToX: (int)x toY: (int)y;? //有兩個(int)類型的參數(shù)x和y
+(BLNPoint*) getOriginPoint; //+表示getOriginPoint是一個類方法
所有方法默認為公有方法叫倍。沒有private或protected方法(可以在接口文件中不要聲明方法,而在實現(xiàn)文件中實現(xiàn)方法來做到類似private方法)豺瘤。
動態(tài)消息發(fā)布:方法調(diào)用通過運行時動態(tài)消息分發(fā)實現(xiàn)吆倦,在對象上調(diào)用方法又稱“向?qū)ο蟀l(fā)送消息”。
例子:
[p1 print]; //實例p1調(diào)用了print方法坐求,也可以說向?qū)ο髉1發(fā)送了一個print消息
[p1 moveToX:100 toY:200]; //向?qū)ο髉1發(fā)送了一個moveToX消息蚕泽,其中還包含了兩個參數(shù),100和200
BLNPoint* origin=[BLNPoint getOriginPoint]; //向BLNPoint類發(fā)送了一個getOriginPoint消息桥嗤,返回值賦值給BLNPoint的類型實例origin
實例方法或類型方法
實例方法用來表達實例的行為所以只能通過實例對象來調(diào)用须妻,實例方法在內(nèi)部實現(xiàn)時可以訪問實例成員包括實例屬性、實例變量和實例方法泛领。也可以訪問類型方法和靜態(tài)變量荒吏。
類方法用來表達類的行為只能通過類來調(diào)用,類型方法在實現(xiàn)時可以訪問類型方法和靜態(tài)變量渊鞋,不能訪問實例成員包括實例屬性绰更、實例變量和實例方法瞧挤。
編譯器背后對實例方法和類方法的不同處理:self指針
例子:
實例方法實現(xiàn)
-(void) print{
????? NSLog(@"[%d, %d]", self.x, self.y);
}
上面的實例方法實現(xiàn)中self實際上是一個隱藏的指針參數(shù),用來傳遞當(dāng)前實例地址,編譯器編譯后用C語言的表達方式可以寫成:
void print(BLNPoint* self){
????? NSLog(@"[%d, %d]", self.x, self.y);
}
調(diào)用該方法時:[p1 print]; //print(p1);
類方法實現(xiàn)
+(BLNPoint*) getOriginPoint{
????? BLNPoint* origin=[[BLNPoint alloc] init];
????? origin.x=0;
????? origin.y=0;
????? return origin;
}
上述的類方法實現(xiàn)編譯后用C語言表示為
BLNPoint* getOriginPoint(){
????? BLNPoint* origin=[[BLNPoint alloc] init];
????? origin.x=0;
????? origin.y=0;
????? return origin;
}
類方法里面不能用self關(guān)鍵字來訪問實例變量动知,但是依然可以使用self關(guān)鍵字皿伺,這時self關(guān)鍵字用來表示當(dāng)前類。在類方法實現(xiàn)里面可以用[self process]來調(diào)用當(dāng)前類中的process方法盒粮,也等同于[BLNPoint process]鸵鸥。
方法參數(shù)
如果參數(shù)類型是值類型,為傳值方式丹皱,如果參數(shù)類型為引用類型妒穴,則為傳指針方式。
方法可以沒有參數(shù)摊崭,也可以沒有返回值讼油。
如果方法有參數(shù),方法名約定包含第一個參數(shù)呢簸,從第二個參數(shù)開始需要顯示提供外部參數(shù)名矮台。
-(void) moveToX: (int)x toY: (int)y;?//toY是第二個參數(shù)的外部參數(shù)名,x是第一個內(nèi)部參數(shù)名根时,y是第二個內(nèi)部參數(shù)名瘦赫。
調(diào)用時,第一個參數(shù)名忽略蛤迎,但后面的參數(shù)名必須顯示標(biāo)明确虱。如: [p1 moveToX:100 toY:200];
動態(tài)方法調(diào)用機制--消息分發(fā)表
在OC里所有的對象類型都可以聲明為id類型
例子:
id obj=[[BLNPoint alloc] init];
[obj moveToX:50 toY:60];
[obj print];
這里類型為id的對象obj可以調(diào)用類型為BLNPoint的對象方法,是由于OC的動態(tài)調(diào)用機制造成的替裆。
OC中調(diào)用所有方法都會通過消息分發(fā)表校辩,上圖灰色的部分其中有一個指針,指向class再指向method list辆童。這樣做可以增加靈活性宜咒,支持在運行時向方法表添加新的方法。缺點是每次調(diào)用方法都要多次尋址有性能損失把鉴。
第五天視頻課程:
初始化器與析構(gòu)器
初始化器和析構(gòu)器是類型的特殊函數(shù)成員故黑,初始化器用于初始化對象實例或者類型。
對象初始化器:-(id)init 可以重載多個纸镊。
例子:
在頭文件中可以聲明多個有不同參數(shù)列表的-(id)init函數(shù)倍阐。
-(id)init;
-(id)initWithName:(NSString *)name;
-(id)initWithName:(NSString *)name WithPages:(int)pages;
-(id)initWithName:(NSString *)name WithPages:(int)pages WithCategory:(NSString *)category;
在主文件中實現(xiàn)聲明的init方法
-(id)init{
????? self = [super init];
????? if(self){? //如果父類初始化失敗self指針將等于Null
??????? NSLog(@"Book Object init“); //在調(diào)用了父類的init方法后可以添加自己所需的內(nèi)容。
????? }
????? return self;
}
-(id)initWithName:(NSString *)name WithPages:(int)pages{
????? return [self initWithName:name WithPages:pages WithCategory:@"General"];
}
-(id)initWithName:(NSString *)name WithPages:(int)pages WithCategory:(NSString *)category{ //由于該初始化器的參數(shù)是最多的,作為主初始化器恒界,其他參數(shù)少的初始化器可以直接調(diào)用主初始化器碉渡。
????? self = [super init];
????? if(self){
????? _name = [name copy]; //在初始化器中使用實例變量而不要使用實例屬性。
????? _pages = pages;
????? _category = [category copy];
????? }
????? return self:
}
初始化對象實例時惫霸,init通常和alloc搭配使用寂汇。
Book *b1 = [[Book alloc]init]; //alloc是一個從NSObject繼承過來的類方法西采。Tips: 按住commond健再點擊關(guān)鍵詞可以查看其類庫罐呼。
Book *b1 = [[Book alloc]init]; 也可以拆分為:
Book *b1 = [Book alloc]鞠柄;
b1 =[b1 init]; //這里等號左邊的b1是不可以省略的,因為[b1 init]有一個返回值嫉柴,是返回一個地址厌杜,OC在這里返回的地址有可能和上一行Book *b1 = [Book alloc];其中的b1地址不一樣计螺。
alloc所做的事情--NSObject已實現(xiàn):1夯尽、在對上分配合適大小的內(nèi)存。 2登馒、將屬性或者實例變量的內(nèi)存置0匙握。
init所做的事情--可以自定義:1、調(diào)用父類初始化器[super init](前置調(diào)用)陈轿。 2圈纺、初始化當(dāng)前對象實例變量。
Book *b1= [Book new]; //new相當(dāng)于調(diào)用 alloc/init的無參數(shù)版本,不能傳遞參數(shù)麦射。
類初始化器
類型初始化器:+(void)initialize 只能有一個蛾娶,負責(zé)類型級別初始化,初始化類里面的靜態(tài)變量法褥。
initialize在每個類使用之前被系統(tǒng)自動調(diào)用茫叭,且每個進程周期中只被調(diào)用一次。
子類的initalize會自動調(diào)用父類的initialize(前置調(diào)用)半等。
+(void)initialize{
????? if(self ==[Book class]){ //判斷該類是否是Book類
??????????? NSLog(@"Book Class initialize");
????? }
}
對象析構(gòu)器
對象析構(gòu)器 -(void)dealloc 只能有一個揍愁,用于釋放對象(沒有類型析構(gòu)器)擁有的動態(tài)資源,無返回值杀饵。
-(void)dealloc{
自動調(diào)用:1.ARC將對象屬性引用計數(shù)減持(-1)
手動實現(xiàn):2.釋放不受ARC管理的動態(tài)內(nèi)存莽囤,如malloc分配的內(nèi)存,關(guān)閉非內(nèi)存資源切距,如文件句柄朽缎、網(wǎng)絡(luò)端口
自動調(diào)用:3.父類dealloc
}
dealloc由ARC根據(jù)對象引用計數(shù)規(guī)則,在釋放對象內(nèi)存前自動調(diào)用谜悟,無法手工調(diào)用话肖。
子類的dealloc會自動調(diào)用父類的dealloc(后置調(diào)用)。
第六天視頻課程:
認識面向?qū)ο?/strong>
封裝 encapsulation:隱藏對象內(nèi)部實現(xiàn)細節(jié)葡幸,對外部僅提供公共接口訪問最筒。
繼承 inheritance:一個類型在另外類型基礎(chǔ)上進行的擴展實現(xiàn)。每一個類只能有一個基類蔚叨,子類自動繼承基類的:實例變量床蜘、屬性辙培、實例方法、類方法邢锯。NSObject類是所有類的根類扬蕊,所有類向上追溯最上面的類都是NSObject類。繼承有兩層含義:1丹擎、成員復(fù)用尾抑,子類復(fù)用基類的成員。所有的成員都會被繼承蒂培,就算是私有成員也被繼承蛮穿,只是成員訪問不到。2毁渗、類型抽象践磅,將子類當(dāng)作父類來使用。
例子:
建立一個類Shape
@interface Shape : NSObject{ //Shape類繼承于NSObject Tips:按住option鍵點擊關(guān)鍵字可以看到相關(guān)的參考文檔灸异。
????? @public int _data; //定義了一個公開的實例變量
}
????? @property int no;
????? -(void)draw;
????? +(void)process;
@end
建立一個Shape的子類Circle
@interface Circle:Shape //Circle類繼承了Shape類
@property int radius; //Circle類自己的實例屬性
@end
由于Circle繼承了Shape類府适,所以Shape類的實例變量、屬性肺樟、實例方法檐春、類方法Circle類都可以使用。
Circle* circle=[[Circle alloc]init];
circle.no=200;
circle->_data++; //在訪問父類實例變量時用->來訪問
[circle draw];
[Circle process]; //Circle類也可以調(diào)用父類的類方法么伯。
第七天視頻課程:
多態(tài) polymorphism:不同類型針對同一行為接口的不同實現(xiàn)方式疟暖。
對比重寫(override)與重載:子類重寫父類同名同參數(shù)方法,子類只可以重寫父類方法田柔。方法名相同俐巴、參數(shù)不同,OC不支持方法的重載(重載指的是方法名相同硬爆,參數(shù)不同欣舵。用不同的參數(shù)傳遞給相同名字的方法,達到不同的運行效果)缀磕。
在子類的代碼中缘圈,可以使用super類調(diào)用基類的實現(xiàn),self具有多態(tài)性袜蚕,可以指向不同子類糟把,super沒有多態(tài)性,僅指向當(dāng)前父類牲剃。
例子:
建立一個Shape的子類Rectangle
@interface Rectangle:Shape
@property int width;
@property int length;
@end
基類Shape中有一個實例方法move:
-(void)move{
????? NSLog(@"Shape object move");
????? [self draw];
}
針對Rectangle類增加了兩個屬性(width和length)重寫(override)繼承過來的方法
@implementation Rectangle
-(id)init{
????? self = [super init];? //重寫時子類初始化器中必須首先調(diào)用基類的初始化器
????? if(self){
??????????? _length = 10;
??????????? _width = 20;
????? }
????? return self;
}
-(void)draw{
????? NSLog(@"Rectangle object draw: length=%d, width=%d", self.length, self.width);
}
-(void)print{
????? NSLog(@"Rectangle Instance variable %d", _data);
}
+(void)process{
????? NSLog(@"Rectangle class process");
}
-(void)dealloc{
?????? NSLog(@"Rectangle dealloc");
}
當(dāng)實例對象調(diào)用時遣疯,Rectangle實例將調(diào)用重寫的方法。Rectangle實例調(diào)用-(void)move時將調(diào)用父類Shape類的實例方法-(void)move颠黎,此方法中調(diào)用的draw方法[self draw]另锋,此時self有多態(tài)性狭归,將調(diào)用Rectangle實例中的draw方法。
對于父類中的屬性也可以在子類中重寫室梅。
父類Shape中的屬性:@property int no;
在子類Rectangle中重寫:
-(int)no{
????? return super.no;? //super表示調(diào)用父類的方法
}
-(int)setNo:(int)no{
????? super.no = no;
}
屬性的重寫本質(zhì)上就是getter和setter兩個訪問器的重寫亡鼠。
繼承中的init和dealloc
初始化器 init:子類自動繼承基類的初始化器,子類也可以重寫初始化器敷待,重寫時子類初始化器中必須首先調(diào)用基類的初始化器(手工調(diào)用)再添加其他內(nèi)容榜揖。
析構(gòu)器 dealloc:子類可以選擇繼續(xù)繼承基類析構(gòu)器,或者重寫基類析構(gòu)器举哟,子類析構(gòu)器執(zhí)行完畢后思劳,會自動調(diào)用基類析構(gòu)器(后置調(diào)用,且不支持手工調(diào)用)妨猩。子類析構(gòu)器自動具有多態(tài)性潜叛。
Tips:盡量避免在父類init和dealloc中調(diào)用子類重寫的方法。
- 文/潘曉璐 我一進店門侥加,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人粪躬,你說我怎么就攤上這事担败∥粞ǎ” “怎么了?”我有些...
- 文/不壞的土叔 我叫張陵提前,是天一觀的道長吗货。 經(jīng)常有香客問我,道長狈网,這世上最難降的妖魔是什么宙搬? 我笑而不...
- 正文 為了忘掉前任,我火速辦了婚禮拓哺,結(jié)果婚禮上勇垛,老公的妹妹穿的比我還像新娘闲孤。我一直安慰自己,他們只是感情好烤礁,可當(dāng)我...
- 文/花漫 我一把揭開白布玻侥。 她就那樣靜靜地躺著决摧,像睡著了一般。 火紅的嫁衣襯著肌膚如雪煌茬。 梳的紋絲不亂的頭發(fā)上改衩,一...
- 文/蒼蘭香墨 我猛地睜開眼较幌,長吁一口氣:“原來是場噩夢啊……” “哼揍瑟!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起乍炉,我...
- 正文 年R本政府宣布,位于F島的核電站糟趾,受9級特大地震影響软瞎,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜拉讯,卻給世界環(huán)境...
- 文/蒙蒙 一涤浇、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧魔慷,春花似錦只锭、人聲如沸。這莊子的主人今日做“春日...
- 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至邀摆,卻和暖如春纵顾,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背栋盹。 一陣腳步聲響...
推薦閱讀更多精彩內(nèi)容
- 蘋果官方文檔翻譯 《Objective-C語言編程》(Programming with Objective-C) ...
- 1. Objective-C簡介 Objective-C語言簡介Objective-C在C語言基礎(chǔ)上做了面向?qū)ο髷U...
- Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理怎茫,服務(wù)發(fā)現(xiàn),斷路器妓灌,智...
- importUIKit classViewController:UITabBarController{ enumD...
- 禪與 Objective-C 編程藝術(shù) (Zen and the Art of the Objective-C C...