iOS.基礎之OC篇

內(nèi)存中的五大區(qū)域

棧:存儲局部變量

堆:程序員手動申請的字節(jié)空間

BSS段:存儲未被初始化的全局變量 靜態(tài)變量

數(shù)據(jù)段(常量區(qū)) :存儲已經(jīng)被初始化的全局變量,靜態(tài)變量,常量數(shù)據(jù),直到程序結束的時候才會被回收

代碼段:存儲程序的代碼,如類第一次訪問時,就把類加載到代碼段

類加載

1).在創(chuàng)建對象的時候.肯定是需要訪問類的

2).聲明1個類的指針變量也會訪問類的

在程序運行期間,當某個類第一次被訪問到的時候,會將這個類存儲到內(nèi)存中的代碼段區(qū)域,這個過程叫做類加載

只有類在第一次被訪問的時候,才會做類加載

一旦類被加載到代碼段以后,直到程序結束的時候才會被釋放

  • 類在代碼段中存儲的步驟?

    a.現(xiàn)在代碼斷種創(chuàng)建個Class對象,Class是Foundation框架中的一個類.

    b.將類的信息存儲在Class對象中,這個Class至少有3個屬性

    類名,屬性,方法,注意:還有一個isa指針,指向父類的類對象

    存儲類的這個Class對象,我們也叫類對象

任何存儲在內(nèi)存中的數(shù)據(jù)都有一個數(shù)據(jù)類型,任何在內(nèi)存中申請的空間也有自己的類型

instancetype

當返回的是該類的對象時,用instancetype

static

1).修飾局部變量(在方法里面的變量).

使局部變量只初始化一次,局部變量在程序中只有一份內(nèi)存,使和這個變量擁有記憶功能(可以被賦值).局部變量的作用域不變,但是生命周期變了(直到程序結束才銷毀)

2).修飾的全局變量

擁有局部變量修飾時候的屬性,不同的是該靜態(tài)變量只能被本文件訪問(作用域在本文件)

訪問修飾符

用來修飾屬性,可以限定對象的屬性在哪個范圍之中訪問

@private:私有 被@private修飾的屬性只能在本類的內(nèi)部訪問(本類的實現(xiàn)中訪問)

@protected:受保護的,被@protected修飾的屬性只能在本類和本類的子類中訪問

@package:被@package修飾的屬性,可以在當前的框架在訪問

@public:公共的,被@public修飾的屬性,可以在任意的地方訪問

  • 注意:如果不為屬性指定訪問修飾符,那么默認的就是@protected
  • 子類仍然可以繼承父類的私有屬性,只不過,在子類中無法去直接訪問從父類繼承過來的私有屬性,如果父類中有一個方法在為屬性賦值或者取值,那么子類可以調(diào)用這個方法間接的訪問父類的私有屬性
  • 訪問修飾符的作用域:從寫訪問修飾符的地方開始往下,直到遇到另外一個修飾符或者結束大括號為止,中間的所有屬性都應用這個訪問修飾符

里氏替換原則

父類指針指向子類對象

當一個父類指針指向子類對象的時候,通過這個父類指針就只能去調(diào)用子類中的父類成員,子類獨有的成員無法訪問

當一個父類的指針指向子類對象時,通過這個父類指針調(diào)用的方法,如果在子類對象中重寫了,調(diào)用的就是子類重寫的方法

多態(tài)

指的是同一個行為,對于不同的事物具有不同的表現(xiàn)形式

結構體和類的區(qū)別

1).結構體只能封裝數(shù)據(jù),而類不僅可以封裝數(shù)據(jù),還可以封裝方法
2).結構體變量分配在棧空間(如果是局部變量的情況下),而對象分配在堆空間

棧空間:空間相對較小,但是存儲在棧中的數(shù)據(jù)訪問效率更高一些

堆空間:空間相對較大,但是存儲在棧中的數(shù)據(jù)訪問效率相對要低

3).賦值

//結構體 Student
Student s = {"小明",19}
//類 Student
Student *s = [Student new];
s.name= @"小明";
s.age = 19;

id

萬能指針.也可以作為返回值.在編譯階段不會去檢查

instancetype

只能作為返回值,返回當前對象

dealloc

重寫父類的dealloc方法時,必須要調(diào)用父類的dealloc方法,即[super dealloc].且要放到方法的最后面.在ARC的機制下,retain,release和dealloc這些方法無法調(diào)用,即[super dealloc]不要去調(diào)用

對象回收的本質

所謂的對象回收,指的是對象占用的空間可以分配給別人,當這個對象占用的空間還沒分配給別人使用之前,其實這個對象的數(shù)據(jù)還在

野指針

已經(jīng)釋放的對象指針,就稱為野指針

僵尸對象

一個已經(jīng)被釋放的對象,但這個對象的空間還沒分配給別人,這樣的對象叫做僵尸對象.

我們通過野指針去訪問僵尸對象的時候,有可能沒問題,也有可能有問題.當僵尸對象占用的空間還沒有分配給別人之前,這是可以訪問的,當僵尸對象占用的空間已經(jīng)分配給別人了,就不允許訪問

@property參數(shù)

@property(參數(shù)1,參數(shù)2,參數(shù)3...)數(shù)據(jù)類型 變量名稱

1.與多線程有關的兩個參數(shù):atomic,nonatomic

atomic:默認值,如果寫atomic,這個時候生成的setter方法的代碼就會被加上一把線程安全鎖.特點:安全,效率低

nonatomic:nonatomic,這個時候生成的setter方法的代碼就不會被加上一把線程安全鎖.特點:不安全,效率高

建議:使用nonatomic

2.與生成的setter方法實現(xiàn)有關的參數(shù):assign,retain(MRC),strong,weak,copy....

assign:默認值,生成的setter方法實現(xiàn)就是直接賦值.在ARC和MRC下都可以使用

retain:只能用在MRC模式下,生成的setter實現(xiàn)就是標準的mrc內(nèi)存格式下的實現(xiàn).先判斷舊的對象和新的對象是不是同一個值,如果不是,就realease舊的,retain新的

使用:當屬性的類型是oc對象的時候就是用retain.當屬性的類型是非oc對象就是用assign

在ARC機制下,當屬性類型是oc對象時,不能使用retain,絕大數(shù)時間應該使用strong

strong強類型指針,weak弱類型指針

3.與生成只讀,讀寫有關的參數(shù):readonly,readwrite

readwrite:默認值,代表同時生成getter和setter.

readonly:只會生成getter,不會生成setter

4.與生成getter,setter方法名字有關的參數(shù):getter,setter

默認情況下,@property生成的getter,setter都是標準的名字.其實我們也可以通過參數(shù)來著指定@property生成的方法的名字

@property(nonatomic,assign,getter=自定義名字)int age

@class和#improt的區(qū)別

import是將指定的文件內(nèi)容拷貝到寫指令的地方,@class并不會拷貝任何內(nèi)容.只是告訴編譯器,這是一個類,這樣編譯器在編譯的時候才可以知道這是一個類

Block

block在oc中是一種數(shù)據(jù)類型
,所以可以作為變量,參數(shù),返回值使用.

語法:返回值類型 (^block名字)(參數(shù)列表) = ^返回值類型(參數(shù)列表){...}

int (^MyBlock)(Nsstring *name) = ^void(Nsstring *name){
    NSLog(@"%@",name);
}
//關于block的簡寫
//如果block表達式(代碼段)中沒有返回值,那么代碼段中的void可以省略
void (^MyBlock)(Nsstring *name) = ^(Nsstring *name){
    ...
}
//注意:1.代碼段中的void可以省略,聲明block變量的返回值無論是什么都不可以省略的.2.如果代碼段中沒有參數(shù),代碼段中表示參數(shù)列表的()也可以省略掉,聲明block變量的參數(shù)()不能省略
void (^MyBlock2)() = ^{
...
    
};
//聲明block變量的時候,如果有指定參數(shù),可以只寫參數(shù)的類型而不寫參數(shù)的名稱
int (^MyBlock3)(int,int) = ^(int num1,int num2){
    ......
};
//注意,這個地方是聲明block變量的時候,寫代碼段的時候類型和形參名字都要寫
//在寫代碼段中,其實無論時候有返回值,都可以省略返回值類型,那么代碼段的返回值類型就感覺代碼段中代碼決定,如果代碼中的返回值和聲明block的返回值不一樣,那么程序就會報錯
NSString (^Block4)(NSString) = (NSString *str){
   return @"你高啊"  
};
//用typedef聲明block
typedef 返回值類型(^Block類型新名)(參數(shù)列表)
//關于block訪問外部變量
1).在block代碼塊內(nèi)部可以取定義在外部的局部變量和全局變量的值.
2).在block代碼塊內(nèi)部可以修改全局變量的值,但不能修改定義在外部的局部變量的值,如果非要改,在局部變量前面加__block的修飾符.
當block作為函數(shù)的返回值時,就必須要使用typedef來定義block的類型,不然會報錯

typedef

使用場景:將一個長類型定義成一個短類型.

在使用block時,可以將長的block聲明定義成一個變量

//如系統(tǒng)的NSUInteger定義
typedef unsigned long NSUInteger;
---------
NS_ASSUME_NONNULL_BEGIN
typedef void (^Block)(NSString *str);
@interface Person : NSObject
@property(nonatomic, copy)Block block;
@end

NS_ASSUME_NONNULL_END

協(xié)議:protocol

作用:專門用來聲明一大堆方法.(不能聲明屬性,也不能實現(xiàn)方法,只能用來寫方的聲明).只要某個類遵守了這個協(xié)議,就相當于擁有個這個協(xié)議中的所有方法聲明,而不用自己去定義

///協(xié)議的聲明
@protocol 協(xié)議名稱 <NSObject>
方法的聲明
@end

///某個類遵守了協(xié)議
@interface 類名: 父類名<協(xié)議名稱>

@end

@required和@optional是專門修飾協(xié)議中的方法.默認是@required
在協(xié)議中被@required修飾的方法,那么遵守這個協(xié)議的類必須要實現(xiàn)這個方法,否則編譯器會發(fā)出警告.
在協(xié)議中,被@optional修飾的方法,那么遵守協(xié)議的這個類可以實現(xiàn)這個方法,也可以不實現(xiàn)這個方法,編譯器不會發(fā)出警告
協(xié)議與協(xié)議之間可以相互繼承.語法:
@protocol 協(xié)議名稱 <父協(xié)議名稱>
@end
 通過協(xié)議的繼承,子協(xié)議中不僅有自己的方法的聲明,還有父協(xié)議中的所有方法的聲明.如果一個類遵守了某個協(xié)議,那么這個類就擁有了這個協(xié)議和這個協(xié)議的父協(xié)議的所有方法的聲明

字符串的 == 判斷(不要用==去判斷字符串是否相等)

NSString *str1 = @"你好";
NSString *str2 = [NSString stringwithFormat:@"你好"];
Bool res = str1 == str2;
NSLog(@"%@",res); //輸出結果是NO
NSString *str3 = @"你好";
NSString *str4 = @"你好";
Bool re1 = str3 == str4;
NSLog(@"%@",res1); //輸出結果是YES
//注意:字符串==判斷是判斷兩個字符串指針的值.用NSString *str1 = @"你好";定義的字符串在常量區(qū)存儲,而且相同的字符串不會重復創(chuàng)建,[NSString stringwithFormat:@"你好"];創(chuàng)建的字符串在堆區(qū),相同的字符串也不會重復創(chuàng)建

copy 拷貝

1).copy是一個方法,定義在NSObject類之中,作用:拷貝對象

NSString -->copy--->不可變字符串 沒有產(chǎn)生新對象,而是直接返回原對象的地址,這種拷貝也稱淺拷貝

NSMutableString-->copy--->是一個不可變字符串對象,產(chǎn)生一個新的對象,這樣的拷貝成為深拷貝
2).mutableCopy定義在NSObject類之中,作用:拷貝對

NSString--->mutableCopy---->可變字符串對象,深拷貝

NSMutableString-->mutableCopy--->可變字符串對象,產(chǎn)生一個新的對象為深拷貝

  • 總結:
  • copy出來的字符串一定是不可變字符串,如果傳入的是可變字符串,會發(fā)生深拷貝,否則是淺拷貝
  • mutableCopy一定是深拷貝,拷貝出來的一定是可變字符串或者數(shù)組,即使傳入的是不可變字符串或者數(shù)組

為什么NSString使用copy修飾也就可以理解了帆吻。使用copy修飾之后士聪,即使屬性拷貝來自可變字符串身腻,也會被深拷貝成不可變字符串能庆,也就是源字符串修改之后不會影響到屬性字符串讶请,增強了代碼的健壯性

%p 打印的是指針變量的值.%@ 打印的是指針指向的對象

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末鸵贬,一起剝皮案震驚了整個濱河市俗他,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌阔逼,老刑警劉巖兆衅,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異嗜浮,居然都是意外死亡羡亩,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門危融,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人吉殃,你說我怎么就攤上這事辞居。” “怎么了蛋勺?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵瓦灶,是天一觀的道長。 經(jīng)常有香客問我迫卢,道長倚搬,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任乾蛤,我火速辦了婚禮每界,結果婚禮上捅僵,老公的妹妹穿的比我還像新娘。我一直安慰自己眨层,他們只是感情好庙楚,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著趴樱,像睡著了一般馒闷。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上叁征,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天纳账,我揣著相機與錄音,去河邊找鬼捺疼。 笑死疏虫,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的啤呼。 我是一名探鬼主播卧秘,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼官扣!你這毒婦竟也來了翅敌?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤惕蹄,失蹤者是張志新(化名)和其女友劉穎蚯涮,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體焊唬,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡恋昼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了赶促。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片液肌。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖鸥滨,靈堂內(nèi)的尸體忽然破棺而出嗦哆,到底是詐尸還是另有隱情,我是刑警寧澤婿滓,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布老速,位于F島的核電站,受9級特大地震影響凸主,放射性物質發(fā)生泄漏橘券。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望旁舰。 院中可真熱鬧锋华,春花似錦、人聲如沸箭窜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽磺樱。三九已至纳猫,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間竹捉,已是汗流浹背芜辕。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留活孩,地道東北人物遇。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像憾儒,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子乃沙,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

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