03

1、成員變量

  • 1 實(shí)例變量(成員變量)既可以在@interface中定義,也可以在@implementation中定義
  • 2 寫在@implementation中的成員變量,默認(rèn)就是私有成員變量,并且和利用@private修飾的不太一樣,在@implementation中定義的成員變量在其他類中無法查看,也無法訪問
  • 3 在@implementation中定義的私有變量只能在本類中訪問

2、@property是一個(gè)編譯器指令

  • 1 在Xocde4.4之前, 可以使用@porperty來代替getter/setter方法的聲明
    也就是說我們只需要寫上@porperty就不用寫getter/setter方法的聲明
    編譯器只要看到@property, 就知道我們要生成某一個(gè)屬性的getter/setter方法
    的聲明

  • 2從Xcode4.4以后apple對(duì)@property進(jìn)行了一個(gè)增強(qiáng), 以后只要利用一個(gè)@property就可以同時(shí)生成setter/getter方法的聲明和實(shí)現(xiàn)
    沒有告訴@property要將傳入的參數(shù)賦值給誰, 默認(rèn)@property會(huì)將傳入的屬性賦值給_開頭的成員變量

  • 3 @property有一個(gè)弊端: 它只會(huì)生成最簡(jiǎn)單的getter/setter方法的聲明和實(shí)現(xiàn), 并不會(huì)對(duì)傳入的數(shù)據(jù)進(jìn)行過濾
    如果想對(duì)傳入的數(shù)據(jù)進(jìn)行過濾, 那么我們就必須重寫getter/setter方法
    如果不想對(duì)傳入的數(shù)據(jù)進(jìn)行過濾, 僅僅是提供一個(gè)方法給外界操作成員變量, 那么就可以使用@property

  • 4 如果利用@property來生成getter/setter方法, 那么我們可以不寫成員變量,
    系統(tǒng)會(huì)自動(dòng)給我們生成一個(gè)_開頭的成員變量
    注意: @property自動(dòng)幫我們生成的成員變量是一個(gè)私有的成員變量, 也就是說是在.m文件中生成的, 而不是在.h文件中生成的

  • 5 如果重寫了setter方法, 那么property就只會(huì)生成getter方法
    如果重寫了getter方法, 那么property就只會(huì)生成setter方法
    如果同時(shí)重寫了getter/setter方法, 那么property就不會(huì)自動(dòng)幫我們生成私有的成員變量

  • 6 readwrite: 代表既生成getter方法 , 也生成setter方法
    默認(rèn)情況下 @property就是readwrite的

  • 7 readonly: 代表只生成getter方法不生成setter方法

3、 @synthesize

  • 1 @synthesize是一個(gè)編譯器指令, 它可以簡(jiǎn)化我們getter/setter方法的實(shí)現(xiàn)
  • 2 什么是實(shí)現(xiàn):
    • 在聲明后面寫上大括號(hào)就代表著實(shí)現(xiàn)
  • 3 在@synthesize后面告訴編譯器, 需要實(shí)現(xiàn)哪個(gè)@property生成的聲明
  • 4 告訴@synthesize, 需要將傳入的值賦值給誰和返回誰的值給調(diào)用者
  • 5 如果在@synthesize后面沒有告訴系統(tǒng)將傳入的值賦值給誰, 系統(tǒng)默認(rèn)會(huì)賦值給和@synthesize后面寫得名稱相同的成員變量
//@synthesize age = _age;

/*
 - (void)setAge:(int)age
 {
    _number = age;
 }
 - (int)age
 {
    return _number
 ;
 }
 */
//@synthesize age = _number;


// 如果在@synthesize后面沒有告訴系統(tǒng)將傳入的值賦值給誰, 系統(tǒng)默認(rèn)會(huì)賦值給和@synthesize后面寫得名稱相同的成員變量
// _age? age;
@synthesize age;

/*
- (void)setAge:(int)age
{
    _age = age;
}

- (int)age
{
    return _age;
}
 */

4、id 類型

  • 1 id是一個(gè)數(shù)據(jù)類型,并且是一個(gè)動(dòng)態(tài)數(shù)據(jù)類型,數(shù)據(jù)類型可以用來,
    • 1 定義變量
    • 2 作為函數(shù)的參數(shù)
    • 3 作為函數(shù)的返回值
  • 2 默認(rèn)情況下所有的數(shù)據(jù)類型都是靜態(tài)數(shù)據(jù)類型,靜態(tài)數(shù)據(jù)類型的特點(diǎn):
    • 1 在編譯時(shí)就知道變量類型
    • 2 知道變量中有哪些屬性和方法
    • 3 在編譯的時(shí)候就可以訪問這些屬性和方法
    • 4 并且如果是通過靜態(tài)數(shù)據(jù)類型定義的變量,如果訪問了不屬于靜態(tài)數(shù)據(jù)類型的方法和屬性,那么編譯器就會(huì)報(bào)錯(cuò)。
  • 3、動(dòng)態(tài)數(shù)據(jù)類型的特點(diǎn)
    • 1 在編譯的時(shí)候編譯器并不知道變量的真是類型,只有在運(yùn)行的時(shí)候才知道它的真是類型 。并且如果通過動(dòng)態(tài)數(shù)據(jù)類型定義變量,如果訪問了不屬于動(dòng)態(tài)數(shù)據(jù)類型的方法和屬性,編譯器就不會(huì)報(bào)錯(cuò)。

id == NSObject * 萬能指針
id和NSObject *的區(qū)別:
NSObject *是一個(gè)靜態(tài)數(shù)據(jù)類型
id 是一個(gè)動(dòng)態(tài)數(shù)據(jù)類型

弊端: 由于動(dòng)態(tài)數(shù)據(jù)類型可以調(diào)用任意方法, 所以有可能調(diào)用到不屬于自己的方法, 而編譯時(shí)又不會(huì)報(bào)錯(cuò), 所以可能導(dǎo)致運(yùn)行時(shí)的錯(cuò)誤

為了避免動(dòng)態(tài)數(shù)據(jù)類型引發(fā)的運(yùn)行時(shí)的錯(cuò)誤, 一般情況下如果使用動(dòng)態(tài)數(shù)據(jù)類型定義一個(gè)變量, 在調(diào)用這個(gè)對(duì)象的方法之前會(huì)進(jìn)行一次判斷, 判斷當(dāng)前對(duì)象是否能夠調(diào)用這個(gè)方法

5 new方法的實(shí)現(xiàn)和原理

  • 1 new做了三件事

1.開辟了存儲(chǔ)空間+alloc 方法
2.初始化所有的屬性(成員變量)- init方法
3.返回對(duì)象的地址

  • 2 alloc 做了什么事情?

1 開辟了存儲(chǔ)空間
2 將所有的屬性設(shè)置為0
3 返回當(dāng)前實(shí)例對(duì)象的地址
注意:1.初始化成員變量, 但是默認(rèn)情況下init的實(shí)現(xiàn)是什么都沒有做
2.返回 初始化后的實(shí)例對(duì)象地址
注意: alloc返回的地址, 和init返回的地址是同一個(gè)地址
建議大家以后創(chuàng)建一個(gè)對(duì)象都使用 alloc init, 這樣可以統(tǒng)一編碼格式

6 構(gòu)造方法

在oc中init開頭的方法,我們稱之為構(gòu)造方法
構(gòu)造方法的用途:用于初始化一個(gè)對(duì)象,讓某個(gè)對(duì)象一創(chuàng)建出來就擁有某些屬性和值

重寫init方法,在init方法中初始化成員變量
注意:重寫init方法必須按照蘋果規(guī)定的格式重寫,如果不按照規(guī)定會(huì)引發(fā)一些未知的錯(cuò)誤

1.必須先初始化父類, 再初始化子類
// 2.必須判斷父類是否初始化成功, 只有父類初始化成功才能繼續(xù)初始化子類
// 3.返回當(dāng)前對(duì)象的地址
- (instancetype)init
{
    // 1.初始化父類
    // 只要父類初始化成功 , 就會(huì)返回對(duì)應(yīng)的地址, 如果初始化失敗, 就會(huì)返回nil
    // nil == 0 == 假 == 沒有初始化成功
    self = [super init];
    // 2.判斷父類是否初始化成功
    if (self != nil) {
        // 3.初始化子類
        // 設(shè)置屬性的值
        _age = 6;
        
    }
    // 4.返回地址
    return self;
}

7 instancetype和id的區(qū)別

如果init方法的返回值是instancetype, 那么將返回值賦值給一個(gè)其它的對(duì)象會(huì)報(bào)一個(gè)警告
如果是在以前, init的返回值是id, 那么將init返回的對(duì)象地址賦值給其它對(duì)象是不會(huì)報(bào)錯(cuò)的

instancetype == id == 萬能指針 == 指向一個(gè)對(duì)象
id在編譯的時(shí)候不能判斷對(duì)象的真實(shí)類型
instancetype在編譯的時(shí)候可以判斷對(duì)象的真實(shí)類型

id和instancetype除了一個(gè)在編譯時(shí)不知道真實(shí)類型, 一個(gè)在編譯時(shí)知道真實(shí)類型以外, 還有一個(gè)區(qū)別
id可以用來定義變量, 可以作為返回值, 可以作為形參
instancetype只能用于作為返回值

注意: 以后但凡自定義構(gòu)造方法, 返回值盡量使用instancetype, 不要使用id

  • 自定義構(gòu)造方法:

其實(shí)就是自定義一個(gè)init方法
1.一定是對(duì)象方法
2.一定返回id/instancetype
3.方法名稱一定以init開頭

8 自定義類工廠方法

自定義類工廠方法是蘋果的一個(gè)規(guī)范, 一般情況下, 我們會(huì)給一個(gè)類提供自定義構(gòu)造方法和自定義類工廠方法用于創(chuàng)建一個(gè)對(duì)象

什么是類工廠方法:

用于快速創(chuàng)建對(duì)象的類方法, 我們稱之為類工廠方法
類工廠方法中主要用于 給對(duì)象分配存儲(chǔ)空間和初始化這塊存儲(chǔ)空間

規(guī)范:

1.一定是類方法 +
2.方法名稱以類的名稱開頭, 首字母小寫
3.一定有返回值, 返回值是id/instancetype

eg:

+ (instancetype)person;

+ (instancetype)person
{
//    return [[Person alloc] init];
    // 注意: 以后但凡自定義類工廠方法, 在類工廠方法中創(chuàng)建對(duì)象一定不要使用類名來創(chuàng)建
    // 一定要使用self來創(chuàng)建
    // self在類方法中就代表類對(duì)象, 到底代表哪一個(gè)類對(duì)象呢?
    // 誰調(diào)用當(dāng)前方法, self就代表誰
    return [[self alloc] init];
}

9 類的本質(zhì)

類的本質(zhì):

 類其實(shí)也是一個(gè)對(duì)象, 這個(gè)對(duì)象會(huì)在這個(gè)類第一次被使用的時(shí)候創(chuàng)建
 只要有了類對(duì)象, 將來就可以通過類對(duì)象來創(chuàng)建實(shí)例對(duì)象
 實(shí)例對(duì)象中有一個(gè)isa指針, 指向創(chuàng)建自己的類對(duì)象
 
 類對(duì)象中保存了當(dāng)前對(duì)象所有的對(duì)象方法
 當(dāng)給一個(gè)實(shí)例對(duì)象發(fā)送消息的時(shí)候, 會(huì)根據(jù)實(shí)例對(duì)象中的isa指針去對(duì)應(yīng)的類對(duì)象中查找

類的啟動(dòng)過程

只要程序啟動(dòng)就會(huì)將所有類的代碼加載到內(nèi)存中, 放到代碼區(qū)
load方法會(huì)在當(dāng)前類被加載到內(nèi)存的時(shí)候調(diào)用, 有且僅會(huì)調(diào)用一次
如果存在繼承關(guān)系, 會(huì)先調(diào)用父類的load方法, 再調(diào)用子類的load方法

當(dāng)當(dāng)前類第一次被使用的時(shí)候就會(huì)調(diào)用(創(chuàng)建類對(duì)象的時(shí)候)
initialize方法在整個(gè)程序的運(yùn)行過程中只會(huì)被調(diào)用一次, 無論你使用多少次這個(gè)類都只會(huì)調(diào)用一次
initialize用于對(duì)某一個(gè)類進(jìn)行一次性的初始化
initialize和load一樣, 如果存在繼承關(guān)系, 會(huì)先調(diào)用父類的initialize再調(diào)用子類的initialize

10 SEL類型

// 1.SEL類型的第一個(gè)作用, 配合對(duì)象/類來檢查對(duì)象/類中有沒有實(shí)現(xiàn)某一個(gè)方法
    /*
    SEL sel = @selector(setAge:);
    Person *p = [Person new];
    // 判斷p對(duì)象中有沒有實(shí)現(xiàn)-號(hào)開頭的setAge:方法
    // 如果P對(duì)象實(shí)現(xiàn)了setAge:方法那么就會(huì)返回YES
    // 如果P對(duì)象沒有實(shí)現(xiàn)setAge:方法那么就會(huì)返回NO
    BOOL flag = [p respondsToSelector:sel];
    NSLog(@"flag = %i", flag);
    
    // respondsToSelector注意點(diǎn): 如果是通過一個(gè)對(duì)象來調(diào)用該方法那么會(huì)判斷該對(duì)象有沒有實(shí)現(xiàn)-號(hào)開頭的方法
    // 如果是通過類來調(diào)用該方法, 那么會(huì)判斷該類有沒有實(shí)現(xiàn)+號(hào)開頭的方法
    SEL sel1 = @selector(test);
    flag = [p respondsToSelector:sel1];
    NSLog(@"flag = %i", flag);
    
    flag = [Person respondsToSelector:sel1];
    NSLog(@"flag = %i", flag);
     */
    
    
    // 2.SEL類型的第二個(gè)作用, 配合對(duì)象/類來調(diào)用某一個(gè)SEL方法
    /*
    SEL sel = @selector(demo);
    Person *p = [Person new];
    // 調(diào)用p對(duì)象中sel類型對(duì)應(yīng)的方法
    [p performSelector:sel];
    
    SEL sel1 = @selector(signalWithNumber:);
    // withObject: 需要傳遞的參數(shù)
    // 注意: 如果通過performSelector調(diào)用有參數(shù)的方法, 那么參數(shù)必須是對(duì)象類型,
    // 也就是說方法的形參必須接受的是一個(gè)對(duì)象, 因?yàn)閣ithObject只能傳遞一個(gè)對(duì)象
    [p performSelector:sel1 withObject:@"13838383438"];
    
    SEL sel2 = @selector(setAge:);
    [p performSelector:sel2 withObject:@(5)];
    NSLog(@"age = %i", p.age);
    
    // 注意:performSelector最多只能傳遞2個(gè)參數(shù)
    SEL sel3 = @selector(sendMessageWithNumber:andContent:);
    [p performSelector:sel3 withObject:@"138383438" withObject:@"abcdefg"];
     */
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,406評(píng)論 6 538
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,034評(píng)論 3 423
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,413評(píng)論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,449評(píng)論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,165評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,559評(píng)論 1 325
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,606評(píng)論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,781評(píng)論 0 289
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,327評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,084評(píng)論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,278評(píng)論 1 371
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,849評(píng)論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,495評(píng)論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,927評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,172評(píng)論 1 291
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,010評(píng)論 3 396
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,241評(píng)論 2 375

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

  • 今天看了一段視頻,被感動(dòng)的淚流滿面。 山東煙臺(tái)棲霞人民醫(yī)院監(jiān)控顯示, 2016年 9月16日早晨7:22從電梯里走...
    新瀾閱讀 287評(píng)論 0 1
  • 左傳曰:人之欲謂之情。我愛我恨我喜我怒謂之情,這恰如其分地表達(dá)了我的情。 婚姻,我愛這種甜蜜的相處...
    劍指閱讀 152評(píng)論 0 0