iOS中關(guān)于類方法和實例方法及self和super

一面褐、關(guān)于類方法和實例方法:

1、類方法:Class Method 有時被稱為靜態(tài)方法充择,類方法可以獨立于實例對象而執(zhí)行德玫。在使用類方法時要注意以下幾點:

  • 類方法以+開頭,相當(dāng)于static椎麦,不能被類的實例調(diào)用宰僧,只能由類對象調(diào)用。
  • 類方法使用self時观挎,self代表類本身即Class琴儿,所以類方內(nèi)可以直接調(diào)用類方法(別調(diào)用自己!死循環(huán)`医荨)造成,不能直接調(diào)用實例方法,但是可以通過創(chuàng)建實例對象來調(diào)用實例方法雄嚣。
  • 類方法中不能訪問屬性和實例變量晒屎,只能訪問類對象,但是可以通過創(chuàng)建實例對象來訪問屬性缓升,有點雞肋~鼓鲁。
@interface JRSecondViewController ()
{
    UIImageView * _imageView;
}
@property(strong,nonatomic)UIButton *btn;
@end

@implementation JRSecondViewController

+(void)creatSomeObject
{
    _imageView = [[UIImageView alloc] init];
    self.btn = [UIButton new];
    [self creatMethod];
    [self creatInstance];
}
+(void)creatMethod{ }

-(void)creatInstance{ }

@end

上面示例報錯詳情

2、實例方法:必須由類的實例對象調(diào)用港谊,可以訪問屬性骇吭,實例變量,同樣可以訪問類對象歧寺,使用限制相對于類方法較少燥狰。

一棘脐、關(guān)于self和super

?總的來說:self會優(yōu)先調(diào)用本類中的方法,super會優(yōu)先調(diào)用父類方法龙致。但是荆残,self是指向本類的指針,是類的隱藏參數(shù)净当,指向當(dāng)前調(diào)用方法的對象(類對象或者實例對象),super卻不是指向父類的指針蕴潦,只是一個編譯器標(biāo)識符像啼,其在運行時中與self相同,指向同一個消息接受者潭苞,只是self會優(yōu)先在當(dāng)前類的methodLists中查找方法忽冻,而super則是優(yōu)先從父類中查找, 向super發(fā)送消息是一種調(diào)用繼承鏈上的超類定義的 方法實現(xiàn)的方法此疹。

// 基類:
@interface BaseViewController : UIViewController

- (id)returnSomething;

@end


@implementation BaseViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    NSLog(@"super -- %@ , self -- %@", [super class], [self class]);
}

- (id)returnSomething
{
    return [UIView new];
}
@end

// 子類:
@interface JRSecondViewController : BaseViewController

@end

@implementation JRSecondViewController

- (instancetype)init
{
    self = [super init];
    if (self) {
        NSLog(@"self == %@", [self class]);
        NSLog(@"super == %@", [super class]);
    }
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // 會從當(dāng)前類的方法列表中開始找,如果沒有,就從父類中再找;
    NSLog(@"viewDidLoad -> self == %@", [self returnSomething]);
    // 如果父類中只用方法定義而未實現(xiàn)則此處會報錯
    NSLog(@"viewDidLoad -> super == %@", [super returnSomething]);
}

-(id)returnSomething
{
    return [UIImageView new];
}
@end

// 外部調(diào)用
JRSecondViewController * secondVC = [JRSecondViewController new];
[self presentViewController:baseNavVC animated:YES completion:^{

}];

// 打印結(jié)果:
17:38:30.721835+0800  self == JRSecondViewController
17:38:30.722161+0800  super == JRSecondViewController
17:38:30.738893+0800  super -- JRSecondViewController , self -- JRSecondViewController
17:38:30.740765+0800  viewDidLoad -> self == <UIImageView: 0x7f9e5e507f30; frame = (0 0; 0 0); userInteractionEnabled = NO; layer = <CALayer: 0x600000029c00>>
17:38:30.741180+0800  viewDidLoad -> super == <UIView: 0x7f9e5e650520; frame = (0 0; 0 0); layer = <CALayer: 0x600000030be0>>

結(jié)果分析:

  • 可以看到首先調(diào)用JRSecondViewControllerinit方法僧诚,但是在其中[self class][super class]均打印的是JRSecondViewController類!原因:
    • 無論[self class]還是[super class]蝗碎,其接受消息的對象都是當(dāng)前 JRSecondViewController 的實例對象湖笨。而不同的是,super是告訴編譯器蹦骑,調(diào)用 class 這個方法時,要去父類的方法,而不是本類里的慈省。
  • 然后到viewDidLoad方法中首先調(diào)用了[super viewDidLoad];去執(zhí)行父類的viewDidLoad方法,但是這里在父類的方法中打印的[self class][super class]同樣指向了JRSecondViewController 類C吖健1甙堋!原因:
    • 還是上面的原因捎废,調(diào)用[super viewDidLoad];方法笑窜,其接收消息的對象依然是JRSecondViewController的是實例對象,但是現(xiàn)在父類中查找viewDidLoad方法登疗。同理在上面代碼的基礎(chǔ)上排截,在父類的returnSomething方法中打印[self class][super class]會是什么結(jié)果呢???

經(jīng)過上面的例子再回來看self和super的實現(xiàn)原理可能更加好理解:

  • self 調(diào)用方法事實際上是通過objc_msgSend(id _Nullable self, SEL _Nonnull op, ...)函數(shù)進(jìn)行消息的發(fā)送谜叹,其中第一個參數(shù)是消息接收者匾寝,第二個參數(shù)op是調(diào)用的具體類的方法的selector,后面是 selector 方法的可變參數(shù)荷腊。如上例所示[self returnSomething]實際上是id _Nullable objc_msgSend(self, @selector(returnSomething))returnSomething方法會從[self class]類中查找艳悔。

  • super調(diào)用方法事實際上是通過id _Nullable objc_msgSendSuper(struct objc_super * _Nonnull super, SEL _Nonnull op, ...)函數(shù)進(jìn)行消息的發(fā)送,但是第一個參數(shù)是一個objc_super結(jié)構(gòu)體女仰。

struct objc_super {
    __unsafe_unretained _Nonnull id receiver;
    __unsafe_unretained _Nonnull Class super_class;
};
  • 此時這個結(jié)構(gòu)體的第一個成員變量receiver就是子類猜年,和 objc_msgSend 中的self相同抡锈。而第二個成員變量super_class就是指父類,調(diào)用 objc_msgSendSuper 的方法時會將這個結(jié)構(gòu)體和returnSomething的selector傳遞過去乔外。

  • 在結(jié)構(gòu)體函數(shù)里面做的事情類似這樣:從objc_super結(jié)構(gòu)體指向的super_class的方法列表開始找 returnSomething的selector床三,找到后再用objc_super->receiver去調(diào)用這個selector。找不到就會報錯杨幼。

這樣結(jié)合上述例子和self和super的原理就會很容易明白為什么[self class][super class]輸出結(jié)果會是一樣的,同時在BaseViewControllerviewDidLoad[self class][super class]輸出都是子類類對象了撇簿。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市差购,隨后出現(xiàn)的幾起案子四瘫,更是在濱河造成了極大的恐慌,老刑警劉巖欲逃,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件找蜜,死亡現(xiàn)場離奇詭異,居然都是意外死亡稳析,警方通過查閱死者的電腦和手機洗做,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來彰居,“玉大人诚纸,你說我怎么就攤上這事≡2ぃ” “怎么了咬清?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長奴潘。 經(jīng)常有香客問我旧烧,道長,這世上最難降的妖魔是什么画髓? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任掘剪,我火速辦了婚禮,結(jié)果婚禮上奈虾,老公的妹妹穿的比我還像新娘夺谁。我一直安慰自己,他們只是感情好肉微,可當(dāng)我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布匾鸥。 她就那樣靜靜地躺著,像睡著了一般碉纳。 火紅的嫁衣襯著肌膚如雪勿负。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天劳曹,我揣著相機與錄音奴愉,去河邊找鬼琅摩。 笑死,一個胖子當(dāng)著我的面吹牛锭硼,可吹牛的內(nèi)容都是我干的房资。 我是一名探鬼主播,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼檀头,長吁一口氣:“原來是場噩夢啊……” “哼轰异!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起暑始,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤溉浙,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蒋荚,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡馆蠕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年期升,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片互躬。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡播赁,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出吼渡,到底是詐尸還是另有隱情容为,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布寺酪,位于F島的核電站坎背,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏寄雀。R本人自食惡果不足惜得滤,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望盒犹。 院中可真熱鬧懂更,春花似錦、人聲如沸急膀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽卓嫂。三九已至慷暂,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間命黔,已是汗流浹背呜呐。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工就斤, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蘑辑。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓洋机,卻偏偏與公主長得像,于是被迫代替她去往敵國和親洋魂。 傳聞我的和親對象是個殘疾皇子绷旗,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,722評論 2 345

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

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,679評論 0 9
  • 1.ios高性能編程 (1).內(nèi)層 最小的內(nèi)層平均值和峰值(2).耗電量 高效的算法和數(shù)據(jù)結(jié)構(gòu)(3).初始化時...
    歐辰_OSR閱讀 29,320評論 8 265
  • 弗蘭克社群作業(yè)03 我的一小時價值200元+3個理由 1.我目前的本職工作時薪是60元副砍,8年醫(yī)技科室工作經(jīng)驗衔肢,能為...
    生活范007閱讀 432評論 0 7
  • 懦弱的男人,密爾豁翎。你那脆弱的情感與無助的內(nèi)心將你交到了對手的陣營中角骤,成了口誅筆伐你腳下領(lǐng)土與繼連王位的最好武器,你...
    白巫師閱讀 1,327評論 0 0
  • 一路蝉揍,三不,六指標(biāo) 這篇短文應(yīng)一位朋友的要求所寫畦娄,謝邀又沾。 無論是年輕人,還是中年人熙卡,在進(jìn)行人生選擇的時候杖刷,都會陷入...
    王佩閱讀 1,236評論 11 47