文档章节

OC中initialize方法和init方法的区别

哪一种黑
 哪一种黑
发布于 2016/02/27 22:09
字数 860
阅读 41
收藏 0

Objective-C中是带有运行时间的。

运行时间好处是,它可以在你的程序运行的流程中进行参与。在Objective-C中,它包括检查是否一个对象可以处理特定的消息,如果不能处理,它就帮助你自动调用其他特定的方法去完成。

initialize不是init


运行时间的行为之一就是initialize。虽然看起来有点像大家常见的init,但是他们并不相同。

在程序运行过程中,它会在你程序中每个类调用一次initialize。这个调用的时间发生在你的类接收到消息之前,但是在它的超类接收到initialize之后。

举个例子,比如一个叫做Duck的类:

#import "Duck.h";
 
@implementation Duck
 
+(void) initialize {
    NSLog(@"Duck initialize");
}
 
-(void) init {
    NSLog(@"Duck init");
}
@end

我们在这里记录initialize和init调用的时间。

我们建立三个Duck对象的实例:

NSLog(@"Hello, World!");

Duck* duck1 = [[Duck alloc] init];

Duck* duck2 = [[Duck alloc] init];

Duck* duck3 = [[Duck alloc] init];
 
看一下记录:

[Session started at 2008-03-23 20:03:25 -0400.]

2016-02-27 20:03:25.869 initialize_example[30253:10b] Hello, World!

2016-02-27 20:03:25.871 initialize_example[30253:10b] Duck initialize

2016-02-27 20:03:25.872 initialize_example[30253:10b] Duck init

2016-02-27 20:03:25.873 initialize_example[30253:10b] Duck init

2016-02-27 20:03:25.873 initialize_example[30253:10b] Duck init

我们可以看到,虽然我们创建了3个Duck的实例,但是initialize仅仅被调用了一次。我们也可以看到,直到我们创建了一个Duck的实例,initialize才被调用。

但是如果Duck有一个子类的话,比如我们建一个Duck的子类叫做Chicken

#import <cocoa/Cocoa.h>

#import "Duck.h"
 
@interface Chicken : Duck {
 
}
 
@end

注意Chicken这个类并没有实现initialize方法。

如果我们同样运行这个程序,但是加上一个Chicken的实例:

NSLog(@"Hello, World!");

Duck* duck1 = [[Duck alloc] init];
Duck* duck2 = [[Duck alloc] init];
Duck* duck3 = [[Duck alloc] init];
    
Chicken* chicken = [[Chicken alloc] init];
 
我们期待看到4个Duck的init调用(因为我们建立了3个Duck和一个Chicken),但是我们看到了这样情况:

[Session started at 2016-02-27 20:13:34 -0400.]

2016-02-27 20:13:34.696 initialize_example[30408:10b] Hello, World!

2016-02-27 20:13:34.698 initialize_example[30408:10b] Duck initialize

2016-02-27 20:13:34.699 initialize_example[30408:10b] Duck init
 
2016-02-27 20:13:34.700 initialize_example[30408:10b] Duck init
 
2016-02-27 20:13:34.700 initialize_example[30408:10b] Duck init
 
2016-02-27 20:13:34.700 initialize_example[30408:10b] Duck initialize
 
2016-02-27 20:13:34.701 initialize_example[30408:10b] Duck init

我们看到了4个Duck的init和2个Duck的initialize方法。这是怎么回事呢?

看来如果一个子类没有实现initialize方法,那么超类会调用这个方法两次,一次为自己,而一次为子类。

我们在Duck的initialize类中记录一下类名,这样可以看得更清楚:
 
+(void) initialize {
   NSLog(@"Duck initialize class:%@",[self class]);
}

现在看明白了:

[Session started at 2016-02-27 20:21:08 -0400.]
 
2016-02-27 20:21:08.816 initialize_example[30513:10b] Hello, World!
 
2016-02-27 20:21:08.818 initialize_example[30513:10b] Duck initialize class:Duck
 
2016-02-27 20:21:08.819 initialize_example[30513:10b] Duck init
 
2016-02-27 20:21:08.820 initialize_example[30513:10b] Duck init
 
2016-02-27 20:21:08.820 initialize_example[30513:10b] Duck init
 
2016-02-27 20:21:08.820 initialize_example[30513:10b] Duck initialize class:Chicken

2016-02-27 20:21:08.821 initialize_example[30513:10b] Duck init

如果你希望确定只用了initialize一次用来实现某些单独运行的工作,或者希望实现仅仅运行一次的方法,检查一下[self class],才能确定是否是你希望做到的效果。


© 著作权归作者所有

哪一种黑
粉丝 8
博文 11
码字总数 9722
作品 0
昌平
私信 提问
Swift编程权威指南第2版 读后收获

  自从参加工作一直在用OC做iOS开发。在2015年的时候苹果刚推出swift1.0不久,当时毕竟是新推出的语言,大家也都很有激情的学习。不过在学完后发现很难在实际项目中使用,再加上当时公司项...

滴水微澜
2018/08/14
0
0
200道iOS面试题面试题整理,底层、技术亮点公司需要的这里都有

100家知名企业今年来iOS面试题合集: 你要的这里都有; 企业要的这里也有; 从基础开始到进阶、深入底层 整理出188个面试题,全是干货 这些全部是题目跟类目,每个题目都会有相对的答案,由于...

_小迷糊
02/13
0
0
XZ_Swift之Swift面向对象

Swift面向对象 1、关于命名空间 在 Swift 中,默认同一个项目中,所有的类都是共享的,可以直接访问,不需要 import 所有对象的属性 var,也可以直接访问到 在Swift中,所有类都默认有一个命名空间...

understand_XZ的博客
2017/12/22
0
0
探秘Runtime - Runtime加载过程

该文章属于原创,转载请注明: https://www.jianshu.com/p/4fb2d7014e9e 程序加载过程 在iOS程序中会用到很多系统的动态库,这些动态库都是动态加载的。所有iOS程序共用一套系统动态库,在程...

刘小壮
2018/11/16
15
0
自定义选项卡实战swift(内附源码且精讲知识点)

App开发本质上是一种对人性的把握,我们在项目开发过程中经常需要自定义很多精美的控件,以此来获得更好的用户体验。 因此,掌握自定义控件是移动应用开发必备的一项技能。本篇文章我们就来快...

充电实践
2018/05/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

一起来学Java8(三)——方法引用

在一起来学Java8(一)——函数式编程中有一个简单的函数式编程的例子: import java.util.function.Consumer;class Person { public static void sayHello(String name) { S...

猿敲月下码
6分钟前
4
0
读书笔记:深入理解ES6(十一)

第十一章 Promise与异步编程   Promise可以实现其他语言中类似Future和Deferred一样的功能,是另一种异步编程的选择,它既可以像事件和回调函数一样指定稍后执行的代码,也可以明确指示代码...

张森ZS
30分钟前
9
0
面试官,Java8 JVM内存结构变了,永久代到元空间

在文章《JVM之内存结构详解》中我们描述了Java7以前的JVM内存结构,但在Java8和以后版本中JVM的内存结构慢慢发生了变化。作为面试官如果你还不知道,那么面试过程中是不是有些露怯?作为面试...

程序新视界
38分钟前
25
0
Elasticsearch 实战(一) - 简介

官腔 Elasticsearch,分布式,高性能,高可用,可伸缩的搜索和分析系统 基本等于没说,咱们慢慢看 1 概述 百度:我们比如说想找寻任何的信息的时候,就会上百度去搜索一下,比如说找一部自己喜...

JavaEdge
42分钟前
18
0
【jQuery基础学习】11 jQuery性能简单优化

本文转载于:专业的前端网站➦【jQuery基础学习】11 jQuery性能简单优化 关于性能优化 合适的选择器 $("#id")会直接调用底层方法,所以这是最快的。如果这样不能直接找到,也可以用find方法继...

前端老手
51分钟前
18
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部