zoukankan      html  css  js  c++  java
  • Objective-C 【init/initWithFrame调用机制】

    这是一个自定义view:

    @implementation MyView
    
    - (instancetype)init {
        if (self = [super init]) {
            NSLog(@"调用了init");
        }
        return self;
    }
    
    - (instancetype)initWithFrame:(CGRect)frame {
        if (self = [super initWithFrame:frame]) {
            NSLog(@"调用了initWithFrame");
        }
        return self;
    }
    
    
    @end

    现在我调用它的init方法:

    MyView *myView = [[MyView alloc] init];

    控制台打印信息是:
    2017-10-09 11:14:35.224 block[2391:262544] 调用了initWithFrame
    2017-10-09 11:14:35.225 block[2391:262544] 调用了init

    问:
    为什么先打印的是initWithFrame而不是init?

    答:

    MyView *myView = [[MyView alloc] init];

    代码调用过程如下:

    1. 动态查找到 MyView 的 init 方法
    2. 调用 super init 方法
    3. super init 方法内部执行的是 [super initWithFrame:CGRectZero]
    4. 然后 super 会发现 MyView 实现了 initWithFrame 方法
    5. 转而执行 [MyView initWithFrame:CGRectZero]
    6. 最后再执行 init 其余部分

    关键点:OC 里面的 super 实际上是让某个类自己去调用父类的方法, 而不是父类去调用某方法。方法动态调用过程中的顺序是按照继承关系从下到上。

    或者:

    init 内部会调用父类的 initWithFrame: 方法,只不过传入的 frame 的值为0,然后父类的 initWithFrame: 方法发现当前的调用对象是子类对象,所以就调用了子类的initWithFrame方法了。这是一个多态的应用。

  • 相关阅读:
    爬虫防止浏览器防止debug处理
    php
    代码日记
    Linux定时任务
    Linux 三剑客(Awk、Sed、Grep)
    golang中使用ETCD
    golang中使用mysql数据库
    golang中使用Redis
    Linux进阶知识和命令
    Linux核心命令使用方法
  • 原文地址:https://www.cnblogs.com/developer-qin/p/8094132.html
Copyright © 2011-2022 走看看