第一次寫(xiě)博客,完全不知道如何寫(xiě),就把隨堂筆記都寫(xiě)到這上面吧。
Objective-c在c語(yǔ)言上做了拓展
cocoa?touch觸摸用戶(hù)體驗(yàn)
主力框架OC及Swift,C/C++可以混合到代碼里
底層思維
抽象思維
“時(shí)空人”
時(shí)間分析:編譯compile時(shí)-運(yùn)行run時(shí)
空間分析:變量放在-內(nèi)存上(棧stack和堆heap)
區(qū)別非常大,決定變量生存周期--比如內(nèi)存泄漏
人物分析:編譯器會(huì)添油加醋
開(kāi)發(fā)方式
Clang或gcc命令行?適合調(diào)試研究微觀的探查
Xcode項(xiàng)目
#import可以避免多次引用的重復(fù)沖突
@autoreleasepool自動(dòng)釋放池
NSlog與printf不同多一個(gè)@不在引號(hào)內(nèi)??多了日期時(shí)間
oc的文件是.m
命令行與linux上的命令基本相似
-fobjc-arc開(kāi)關(guān)語(yǔ)句/開(kāi)關(guān)命令支持了arc的內(nèi)存引用技術(shù)管理?該機(jī)制對(duì)內(nèi)存管理影響大
-o??output輸出??后跟文件名
clang?-help命令手冊(cè)
Xcode項(xiàng)目?構(gòu)建正規(guī)工程項(xiàng)目?使用大型框架,追求設(shè)計(jì)質(zhì)量和代碼組織
1.Creat?a?new?Xcode?project
2.OS?X→Application→Command?Line?Tool
3.******名字
4.選擇目錄
5.main.m
6.build&run
GCC古老的編譯器可以跨平臺(tái)?開(kāi)源
LLVM?low?level?virtual?machine
optimizer優(yōu)化器
Code?Generator代碼生成器
Programming?with?Objective-C必讀文檔
蘋(píng)果官方文檔:https://developer.apple.com/library/
Programming?with?Objective-C
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/
ios專(zhuān)區(qū)https://developer.apple.com/library/ios/
蘋(píng)果開(kāi)發(fā)者大會(huì)WWDC
https://developer.apple.com/videos/wwdc/2015
本節(jié)課代碼
#import
int?main(int?argc,?const?*?argv[])
{
@autoreleasepool
{
NSlog(@"Hello,world!");
}
return?0;
}
類(lèi)型系統(tǒng)
值類(lèi)型value?type(c語(yǔ)言)
·基礎(chǔ)數(shù)值類(lèi)型
·結(jié)構(gòu)struct
·枚舉enum
引用類(lèi)型reference?type
·類(lèi)class(面向?qū)ο螅?/p>
·指針pointer
·塊block
類(lèi)型裝飾
·協(xié)議protocol
·類(lèi)別category
·擴(kuò)展extension
接口文件rpoint.h
@interface?RPoint:NSObject繼承
@property?int?x;定義一個(gè)屬性?類(lèi)似c中的字段
@property?int?y;//狀態(tài)????里面放了數(shù)據(jù)成員
-(void)?print;//行為
@end
實(shí)現(xiàn)文件
#import
#import"rpoint.h"
@implementation?RPoint
-(void)print{
NSlog(@"[%d,%d]",self.x,self.y);//self表示當(dāng)前的對(duì)象
}
@end
//創(chuàng)建對(duì)象
RPoint*?rp1=[[RPoint?alloc]?init];//RPoint是一個(gè)類(lèi)型,rp1是一個(gè)實(shí)例,alloc是向系統(tǒng)請(qǐng)求分配內(nèi)存的一個(gè)過(guò)程,加中括號(hào)是方法或消息的調(diào)用;init=initialize初始化,會(huì)調(diào)用默認(rèn)構(gòu)造器,會(huì)把x,y初始化成0;該語(yǔ)句是動(dòng)態(tài)的向系統(tǒng)請(qǐng)求內(nèi)存分配
typedef?struct{//結(jié)構(gòu)里面不能寫(xiě)類(lèi)里面像print之類(lèi)的方法
int?x;
int?y;
}SPoint;
[rp1?print];//給rp1發(fā)送一個(gè)print的消息
SPoint?sp1;//自動(dòng)分配內(nèi)存,結(jié)構(gòu)對(duì)應(yīng)的實(shí)例,叫做值
rp1可以發(fā)消息,sp1不可以,可見(jiàn)RPoint有一個(gè)面向?qū)ο蟮奶卣?/p>
變量在哪---畫(huà)運(yùn)行時(shí)的內(nèi)存圖
rp1棧上存儲(chǔ)指針,0x00588系統(tǒng)隨機(jī)分配,指向的堆上面的對(duì)象,訪(fǎng)問(wèn)對(duì)象需通過(guò)指針訪(fǎng)問(wèn)
sp1在棧上直接存儲(chǔ)了值
棧stack
·無(wú)ARC(自動(dòng)引用基數(shù))負(fù)擔(dān),由系統(tǒng)自動(dòng)管理,以執(zhí)行函數(shù)為單位
·空間大小編譯時(shí)確定(參數(shù)+局部變量)
·函數(shù)執(zhí)行時(shí),系統(tǒng)會(huì)自動(dòng)分配一個(gè)stack
·函數(shù)執(zhí)行結(jié)束,系統(tǒng)會(huì)立即自動(dòng)回收或銷(xiāo)毀stack
·函數(shù)之間通過(guò)拷貝值傳遞
·具有局部性,大小有限額,一般就幾M,超出會(huì)產(chǎn)生一個(gè)stack?overflow,一般棧不會(huì)溢出,除非寫(xiě)成死循環(huán)或超大遞歸
堆heap
·分配由程序員手動(dòng)請(qǐng)求(創(chuàng)建對(duì)象時(shí))
·釋放有兩種機(jī)制,用的較多時(shí)ARC自動(dòng)釋放(確定時(shí))
·函數(shù)之間通過(guò)拷貝引用(指針)傳遞
·具有全局性,總體無(wú)大小限制(受制于系統(tǒng)內(nèi)存整體大小)
堆是最自由也是最不容易出問(wèn)題的--內(nèi)存泄露
棧的負(fù)擔(dān)很清,堆需要程序員操心的
RPoint*?rp2=rp1//拷貝
rp2.x++;
rp2.y++;???//rp1的堆值也會(huì)改變
SPoint?sp2=sp1;//拷貝
sp2.x++;
sp2.y++;//sp1的值不變
傳參?本質(zhì)上就是拷貝
void?process(*rp3,sp3);
傳參調(diào)用完畢,process棧會(huì)被回收
數(shù)據(jù)成員-屬性與實(shí)際變量
成員扮演類(lèi)的**功能非常重要的角色
數(shù)據(jù)成員data?member描述對(duì)象狀態(tài)
·實(shí)例變量instance?variable對(duì)內(nèi)的
·屬性property對(duì)外的
函數(shù)成員function?member描述對(duì)象行為
·方法method
·初始化器init
·析構(gòu)器dealloc
人識(shí)屬性
·屬性表達(dá)的是實(shí)例的狀態(tài),描述的是類(lèi)型的對(duì)外接口,
編譯器回為屬性定義生成三種構(gòu)造
·一個(gè)getter訪(fǎng)問(wèn)器方法
·一個(gè)setter訪(fǎng)問(wèn)器方法
·一個(gè)實(shí)例變量
訪(fǎng)問(wèn)器方法
[employee?setFirstName:?@"Tom"];
NSlog(@"First?Name:?%@",[employee?firstName]);
屬性表達(dá)式(點(diǎn)表達(dá)式)=訪(fǎng)問(wèn)器方法
employee.LastName=@"Chen";
NSlog(@"Last?Name:?%@",employee.lastName);
employee.age=32;對(duì)象,只能訪(fǎng)問(wèn)實(shí)例屬性
Employee.max=400;類(lèi),可以訪(fǎng)問(wèn)類(lèi)屬性(模擬出來(lái)的).max=setmax
//employee._tempCount=100;類(lèi)外不可以訪(fǎng)問(wèn)實(shí)例變量,類(lèi)外只能訪(fǎng)問(wèn)屬性
@synthesize
更改的不是屬性的名字,是屬性后對(duì)應(yīng)的實(shí)例變量名字
如果自定義了getter和setter訪(fǎng)問(wèn)器方法,或針對(duì)只讀屬性定義了getter訪(fǎng)問(wèn)器方法,編譯器將不再合成實(shí)例變量
屬性是公有的??類(lèi)外
實(shí)例變量是私有的?類(lèi)內(nèi)
在類(lèi)外一律使用屬性來(lái)訪(fǎng)問(wèn),類(lèi)內(nèi)大多也通過(guò)self使用屬性訪(fǎng)問(wèn),只有以下情況使用實(shí)例變量來(lái)訪(fǎng)問(wèn)://生存周期非常獨(dú)特
·初始化器init
·析構(gòu)器dealloc
·自定義訪(fǎng)問(wèn)器方法
實(shí)例變量的生存周期
·實(shí)例變量的存儲(chǔ),跟隨對(duì)象實(shí)例存儲(chǔ)在堆上
·值類(lèi)型實(shí)例變量直接“內(nèi)嵌”在對(duì)象實(shí)例中,跟隨對(duì)象實(shí)例內(nèi)存釋放而被釋放
·引用類(lèi)型實(shí)例變量通過(guò)指針“引用”堆上的引用類(lèi)型實(shí)例,ARC針對(duì)引用進(jìn)行計(jì)數(shù)管理,自動(dòng)釋放引用計(jì)數(shù)為0的對(duì)象
屬性的描述特性(Attribute)
·讀寫(xiě)屬性readwrite
·只讀屬性readonly
·多線(xiàn)程特性
·原子性atomic?//要么完成,要么徹底不執(zhí)行,不會(huì)被其他線(xiàn)程搶走
·非原子性nonatomic
·內(nèi)存管理特性
·ARC環(huán)境
·強(qiáng)引用strong//可能出現(xiàn)循環(huán)引用,并導(dǎo)致內(nèi)存泄露,
·弱引用weak//防止循環(huán)引用
·拷貝屬性copy創(chuàng)建獨(dú)立拷貝
函數(shù)成員
全局函數(shù)(c語(yǔ)言)
NSlog?c風(fēng)格的全局函數(shù)
成員函數(shù)(ObjC方法)
都是代碼段上的可執(zhí)行序列
方法是類(lèi)的成員函數(shù),表達(dá)實(shí)力行為或類(lèi)型行為。
減號(hào)代表實(shí)例方法???返回值用括弧擴(kuò)起來(lái)
-(void)?print;
-(BOOL)?isEqualToPoint:(BLNPoint*)?point;//方法名稱(chēng)后跟的冒號(hào),后面是參數(shù)
-(void)?moveToX:(int)x?toY:(int)y;?//多個(gè)參數(shù)
加號(hào)是類(lèi)型方法
函數(shù)實(shí)現(xiàn)里面的大括號(hào),即方法體
所有方法默認(rèn)為公有方法。沒(méi)有private或protected方法
實(shí)現(xiàn)私有方法的小技巧
接口文件不用方法,實(shí)現(xiàn)文件放方法
動(dòng)態(tài)消息分發(fā):(由于)方法調(diào)用通過(guò)運(yùn)行時(shí)動(dòng)態(tài)消息分發(fā)實(shí)現(xiàn),(所以)在對(duì)象上調(diào)用方法,又稱(chēng)向?qū)ο蟀l(fā)送消息
實(shí)例方法--表達(dá)實(shí)例行為,只可以通過(guò)實(shí)例調(diào)用
類(lèi)方法--表達(dá)類(lèi)型行為,只能通過(guò)類(lèi)型調(diào)用
實(shí)例屬性用self.來(lái)訪(fǎng)問(wèn)
了解編譯器背后對(duì)實(shí)例方法
void?print(BLNPoint*?self){
NSlog("")
}
[p1?print];//print(p1);
面向?qū)ο蟮乃季S方式
對(duì)象+行為//傳統(tǒng)的結(jié)構(gòu)化編程:算法+結(jié)構(gòu)
類(lèi)方法里可以用self
不可以self.x=100;是指針。。。不表示實(shí)例
可以[self?process];//等同于[BLNPoint?Process];是類(lèi)
+(void)?process{
NSLog(@"process...");
}
BLNPoint*?origin=[BLNPoint?getOriginPoint];
//BLNPoint*?origin=getOriginPoint();C語(yǔ)言全局變量形式
如果參數(shù)類(lèi)型為值類(lèi)型,則為傳值方式:如果參數(shù)類(lèi)型引用類(lèi)型,則為傳指針?lè)绞?/p>
方法可以沒(méi)喲參數(shù),也可以沒(méi)有返回值
如果方法有參數(shù),方法名約定包涵第一個(gè)參數(shù)名(只需要內(nèi)部參數(shù)),從第二個(gè)參數(shù)開(kāi)始需要顯示提供外部參數(shù)名
動(dòng)態(tài)方法調(diào)用機(jī)制
灰色部分有一部分是指針,指著class
有性能負(fù)擔(dān)
初始化器和析構(gòu)器
對(duì)象初始化器:-(id)?init可以重載多個(gè)
類(lèi)型初始化器:+(void)initalize只能有一個(gè)
對(duì)象析構(gòu)器:-(void)dealloc只能有一個(gè)
沒(méi)有類(lèi)型析構(gòu)器
初始化對(duì)象實(shí)例時(shí),init通常和alloc搭配使用
alloc是類(lèi)方法
查看類(lèi)庫(kù)?按住command鍵?點(diǎn)擊鼠標(biāo)
alloc所做的事情--NSObject以實(shí)現(xiàn):
·在堆上分配合適大小的內(nèi)存
·將屬性或者實(shí)例變量的內(nèi)存置0.(指針為0)
init所做的事情--可以用系統(tǒng)合成的也可以自定義:
·調(diào)用父類(lèi)初始化器配[super?init]//前置調(diào)用
·初始化當(dāng)前對(duì)象實(shí)例變量//注意使用實(shí)例變量,不要使用屬性
new相當(dāng)于?調(diào)用alloc/init的無(wú)參數(shù)版
~類(lèi)初始化器
·類(lèi)初始化器initialize負(fù)責(zé)類(lèi)型級(jí)別的初始化
·initialize在每個(gè)類(lèi)使用之前被系統(tǒng)自動(dòng)調(diào)用,且每個(gè)進(jìn)程周期中,只被調(diào)用一次
·子類(lèi)的initialize會(huì)制動(dòng)調(diào)用父類(lèi)的initialize//前置調(diào)用
1.自動(dòng)調(diào)用:ARC對(duì)對(duì)象屬性的引用技術(shù)減持
2.手工實(shí)現(xiàn)
NSLog(@"ads");
非內(nèi)存資源,非托管資源,需手工關(guān)閉
3.自動(dòng)調(diào)用:父類(lèi)dealloc后置
dealloc由ARC根據(jù)對(duì)象引用計(jì)數(shù)規(guī)則,在釋放對(duì)象內(nèi)存前自動(dòng)調(diào)用,無(wú)法手工調(diào)用。
面向?qū)ο?br>
封裝encapsulation
繼承inheritance
一個(gè)類(lèi)型在另外類(lèi)型基礎(chǔ)上新型擴(kuò)展實(shí)現(xiàn)
多態(tài)polymorphism
不同類(lèi)型針對(duì)同一行為接口的不同實(shí)現(xiàn)方式
繼承到底繼承了什么?
·實(shí)例變量
·屬性
·實(shí)例方法//(初始化器和析構(gòu)器是特殊的實(shí)例方法)
·類(lèi)方法
大寫(xiě)的是類(lèi)?小寫(xiě)的是對(duì)象
NSObject是所有類(lèi)的根類(lèi),祖先類(lèi)
按住option經(jīng)??碞SObject幫助文檔
繼承的兩層含義:
·成員復(fù)用:子類(lèi)復(fù)用基類(lèi)成員
·類(lèi)型抽象:將子類(lèi)當(dāng)作父類(lèi)來(lái)使用(is-a關(guān)系準(zhǔn)則)子類(lèi)可以使用父類(lèi)成員
私有的成員也是都被繼承的
子類(lèi)只是訪(fǎng)問(wèn)不到
多態(tài)
運(yùn)行時(shí)多態(tài)
子類(lèi)在父類(lèi)統(tǒng)一行為接口下,表現(xiàn)不同的實(shí)現(xiàn)方式
//override重寫(xiě)
//Shape是聲明類(lèi)型
//Rectangle是實(shí)際類(lèi)型
[shape?draw];//多態(tài)調(diào)用
[rect?draw];//多態(tài)調(diào)用:函數(shù)地址的動(dòng)態(tài)辨析,效率較低
[rect?print];//多態(tài)調(diào)用
子類(lèi)重寫(xiě)父類(lèi)同名同參數(shù)方法:子類(lèi)只可以重寫(xiě)父類(lèi)方法
方法名相同、參數(shù)不同:OC不支持方法的重載
在子類(lèi)代碼中??梢允褂胹uper來(lái)調(diào)用基類(lèi)的實(shí)現(xiàn)。
·self具有多態(tài)性,可以指向不同子類(lèi)
·super沒(méi)有多態(tài)性,僅指向父類(lèi)
~繼承中的init和dealloc
初始化器init
·子類(lèi)自動(dòng)繼承基類(lèi)的初始化器
·子類(lèi)也可以重寫(xiě)基類(lèi)初始化器,此時(shí)子類(lèi)初始化器必須首先調(diào)用基類(lèi)的一個(gè)初始化器(手工調(diào)用)
析構(gòu)器dealloc
·子類(lèi)可以選擇繼承基類(lèi)析構(gòu)器,或者重寫(xiě)基類(lèi)析構(gòu)器
·子類(lèi)析構(gòu)器執(zhí)行完畢后,會(huì)自動(dòng)調(diào)用基類(lèi)析構(gòu)器(后置調(diào)用,且不支持手工調(diào)用)
·子類(lèi)析構(gòu)器自動(dòng)具有多態(tài)性
Tips:盡量避免在父類(lèi)init和dealloc中調(diào)用子類(lèi)重寫(xiě)方法