一万小时定律的遗憾之Objective-C的self与super

Malcolm T.Gladwell说:“人们眼中的天才之所以卓越非凡,并非天资超人一等,而是付出了持续不断的努力。1万小时的锤炼是任何人从平凡变成超凡的必要条件。”

对于一万小时定律,我是深信不疑的,然而真的尝试做着的时候,才发现一万小时,对于天资愚钝的我还远远不够。

学习Objective-C已近两年,每天的工作学习的平均时间也控制在十个小时以上,渐渐地一直以为自己对其机制及语法有了一定认识,然而看到别人对两个编程中最常用到关键字self、super的理解的时候,实在羞愧,深感自己对平日使用的东西了解还太少太少。

super.jpg

正文

当然,这一切都要从一个Model和一个网上的笔试题说起:

1、一个Model
#import <Foundation/Foundation.h>

@interface EVNHelper : NSObject
- (instancetype)init;
@end

#import "EVNHelper.h"

@implementation EVNHelper

- (instancetype)init
{
    self = [super init];// ???
    if (self)
    {
       // other init code 
    }
    return self;
}
@end
2、 一个笔试题
- (instancetype)init
{
    self = [super init]; 
    if (self)
    {
        NSLog(@"self className is %@", NSStringFromClass([self class]));
        NSLog(@"super  className is %@", NSStringFromClass([super class]));

        NSLog(@"self superclass  className is %@", NSStringFromClass([self superclass]));
        NSLog(@"super superclass  className is %@", NSStringFromClass([super superclass]));
    }
    return self;
}
@end

输出:
    2016-12-24 16:04:32.600 Demo[6009:1006834] self className is EVNHepler
    2016-12-24 16:04:32.601 Demo[6009:1006834] super  className is EVNHepler
    2016-12-24 16:04:32.601 Demo[6009:1006834] self superclass  className is NSObject
    2016-12-24 16:04:32.602 Demo[6009:1006834] super superclass  className is NSObject

对应的问题也来了:

1、子类初始化为什么要写self = [super init],意义?
2、为什么[self class]和 [super class];[self superclass]和[super superclass]输出相同?

可到底self和super是什么呢?(由于对runtime懂得太少,怕误人子弟,暂不扯底层代码,只说自己能看到的)

  • self
    之前我的理解,self是对象指针,指向当前类的实例对象。其实这种理解是不准确的,因为在静态方法self 依然可以使用(如下代码),这怎么解释呢!
+ (void)helperMethodA
{
    [self helperMethodB];
}
+ (void)helperMethodB
{
    NSLog(@"asdfasdfasd");
}

带着这份好奇,最终我在NSObject协议中找到了self,原来self是返回instancetype类型的代理方法,但又有些奇怪,我们在自定义子类的时候并没有实现这个方法,我认为self的功能,OC已经帮我们实现,只是我们看不到而已。这样就明确了,self最终返回的结果就是instancetype类型的东西,它是动态类型,最终运行时才会确定,实例方法返回实例类型、静态方法返回的是Class。

#include <objc/objc.h>
#include <objc/NSObjCRuntime.h>

@class NSString, NSMethodSignature, NSInvocation;
@protocol NSObject

- (BOOL)isEqual:(id)object;
@property (readonly) NSUInteger hash;
@property (readonly) Class superclass;
......
- (Class)class OBJC_SWIFT_UNAVAILABLE("use 'anObject.dynamicType' instead");
- (instancetype)self;
......
@end

  • super
    在Foundation框架中,super是找不到的,该关键字应该是比self更为奇特的东西。虽然找不到super,但我们可以看到结构体objc_super,在官方解释中我们能看到一些端倪。

objc_super: The compiler generates an objc_super data structure when it encounters the super keyword as the receiver of a message. It specifies the class definition of the particular superclass that should be messaged.

大致意思就是,当遇到super关键字时,编译器会生成一个objc_super结构体,作为消息的接收者,objc_super结构体使得接收消息的父类的定义被明确化。
所以,super的含义应该是一种编译指令,它的作用用来给父类发送消息,并返回消息响应的结果。

#include <objc/objc.h>
#include <objc/runtime.h>

#pragma GCC system_header

#ifndef OBJC_SUPER
#define OBJC_SUPER

/// Specifies the superclass of an instance. 
struct objc_super {
    /// Specifies an instance of a class.
    __unsafe_unretained id receiver;
    /// Specifies the particular superclass of the instance to message. 
#if !defined(__cplusplus)  &&  !__OBJC2__
    __unsafe_unretained Class class;
#else
    __unsafe_unretained Class super_class;
#endif
};

知悉了这两点,上面的两个问题也就迎刃而解了。

解答:

问题一:self = [super init]是面向对象思想的一种体现,意义就是,利用父类的init方法为子类初始化父类的公有属性。
问题二:理解这个先要明确alloc和init的区别,alloc为对象开辟内存,init是对象初始化,所以,[super init] 是初始化在子类上的,super发出消息的主体对象是子类,和self是同一个对象。 class方法和self类似是NSObject协议中的代理方法,我认为class的功能,OC也已经帮我们实现在每个子类中,只是我们看不到而已,所以不管是super还是self发出的class消息,执行的时候,都在子类中,返回的都是子类。

参考:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容

  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 1,678评论 0 9
  • 我们常常会听说 Objective-C 是一门动态语言,那么这个「动态」表现在哪呢?我想最主要的表现就是 Obje...
    Ethan_Struggle阅读 2,170评论 0 7
  • 原文出处:南峰子的技术博客 Objective-C语言是一门动态语言,它将很多静态语言在编译和链接时期做的事放到了...
    _烩面_阅读 1,214评论 1 5
  • 新雨茫漓落惊春,又洗飞花月烛尘。 清风不许夜灯火,且过蓬门吹旧人。 芳华最是有情处,萧然久逝香无痕。 长歌犹在阳城...
    不知世间何事阅读 337评论 0 1
  • 2.早晨六点起来,给家里人煎了土豆饼,并让弟媳妇带到单位吃,她会倍感温暖吧! 3.中午包饺子,给妈妈熬中药泡脚,每...
    竹林千顷田华阅读 165评论 0 0