1、先把OC的类分清楚各有什么方法

  • 普通类的方法 
    init 
    initialize:
  • 控制器类的方法 
    init 
    initialize: 
    initWithCoder:
  • UI控件类的方法 
    init 
    initialize: 
    initWithCoder: 
    initWithFrame:

2、init方法 
每个类被创建的时候就会调用init方法

Person *p1 = [[Person alloc]init];
Person *p2 = [[Person alloc]init];
Person *p3 = [[Person alloc]init];
Person *p4 = [[Person alloc]init];

 

打印信息

2015-10-14 10:42:58.852 afgasdgsdfsd[856:19063] Person---init---Person
2015-10-14 10:42:58.852 afgasdgsdfsd[856:19063] Person---init---Person
2015-10-14 10:42:58.853 afgasdgsdfsd[856:19063] Person---init---Person
2015-10-14 10:42:58.853 afgasdgsdfsd[856:19063] Person---init---Person

 

在有继承关系的情况下,比如Student类继承Person类,那么在不重写子类的init方法时,创建子类对象

Person *p1 = [[Person alloc]init];
Person *p2 = [[Person alloc]init];
Person *p3 = [[Person alloc]init];
Person *p4 = [[Person alloc]init];
Student *s = [[Student alloc] init];

- (instancetype)init{

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

 

打印信息

2015-10-14 11:00:43.569 afgasdgsdfsd[904:22876] Person---init---Person
2015-10-14 11:00:43.569 afgasdgsdfsd[904:22876] Person---init---Person
2015-10-14 11:00:43.569 afgasdgsdfsd[904:22876] Person---init---Person
2015-10-14 11:00:43.569 afgasdgsdfsd[904:22876] Person---init---Person
2015-10-14 11:00:43.569 afgasdgsdfsd[904:22876] Person---init---Student

 
如果子类重写了init方法,也会先调用父类的init。
 
3、initialize: 
这个类跟init经常混淆,但是还是有区别的,我们先看看调用的顺序
#import "Person.h"

@implementation Person
- (instancetype)init{

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

+ (void)initialize{

if ( self == [Person class]) {
        NSLog(@"Person----initialize---%@",[self class]);
    }
}
@end

2015-10-14 11:00:43.568 afgasdgsdfsd[904:22876] Person----initialize---Person
2015-10-14 11:00:43.569 afgasdgsdfsd[904:22876] Person---init---Person
2015-10-14 11:00:43.569 afgasdgsdfsd[904:22876] Person---init---Person
2015-10-14 11:00:43.569 afgasdgsdfsd[904:22876] Person---init---Person
2015-10-14 11:00:43.569 afgasdgsdfsd[904:22876] Person---init---Person

 

我们可以看到先打印initialize:方法,而且只打印的一次,为什么呢? 
在程序运行过程中,它会在你程序中每个类调用一次initialize。这个调用的时间发生在你的类接收到消息之前,但是在它的超类接收到initialize之后。 
系统在第一次使用这个类的时候调用(一个类只会调用一次) 
如果在有继承关系的情况下有三种 
一、父类重写:只有父类调用 
二、子类重写:只有子类调用 
三、父子类重写:父子类调用

#import "Person.h"

@implementation Person
- (instancetype)init{

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

+ (void)initialize{

if ( self == [Person class]) {
        NSLog(@"Person----initialize---%@",[self class]);
    }
}
@end

Alex 2015/10/14 11:17:25
#import "Student.h"

@implementation Student

- (instancetype)init{

if (self = [super init]) {
        NSLog(@"Student---init");
    }
    return self;
}

+ (void)initialize{

if ( self == [Student class]) {
        NSLog(@"Student----initialize---%@",[self class]);
    }
}

@end
 
 Person *p1 = [[Person alloc]init];
    Person *p2 = [[Person alloc]init];

Student *s = [[Student alloc] init];

2015-10-14 11:17:54.500 afgasdgsdfsd[970:26330] Person----initialize---Person
2015-10-14 11:17:54.501 afgasdgsdfsd[970:26330] Person---init---Person
2015-10-14 11:17:54.501 afgasdgsdfsd[970:26330] Person---init---Person
2015-10-14 11:17:54.501 afgasdgsdfsd[970:26330] Student----initialize---Student
2015-10-14 11:17:54.502 afgasdgsdfsd[970:26330] Person---init---Student
2015-10-14 11:17:54.502 afgasdgsdfsd[970:26330] Student---init

4、initWithCoder: 
这个方法时遵守了NSCoding协议 
苹果官方的解释是:

The NSCoding protocol declares the two methods that a class must implement so that instances of that class can be encoded and decoded. This capability provides the basis for archiving (where objects and other structures are stored on disk) and distribution (where objects are copied to different address spaces).

In keeping with object-oriented design principles, an object being encoded or decoded is responsible for encoding and decoding its instance variables. A coder instructs the object to do so by invoking encodeWithCoder: or initWithCoder:. encodeWithCoder: instructs the object to encode its instance variables to the coder provided; an object can receive this method any number of times. initWithCoder: instructs the object to initialize itself from data in the coder provided; as such, it replaces any other initialization method and is sent only once per object. Any object class that should be codable must adopt the NSCoding protocol and implement its methods.

It is important to consider the possible types of archiving that a coder supports. On OS X version 10.2 and later, keyed archiving is preferred. You may, however, need to support classic archiving. For details, see Archives and Serializations Programming Guide.

翻译: 
NSCoding协议声明了两个方法,一个类必须实现,因此这类的实例可以编码和解码。此功能提供了依据归档(对象和其他结构存储在磁盘上)和销售(对象被复制到不同地址空间)。

符合面向对象的设计原则,一个物体被编码或解码负责编码和解码实例变量。这样做的一个编码器指示对象通过调用encodeWithCoder:或initWithCoder:。encodeWithCoder:指示对象实例变量提供的编码器,编码一个对象可以接收这个方法任意次数。initWithCoder:指示对象初始化本身从编码器提供的数据;因此,它将取代任何其他初始化方法和每个对象只发送一次。任何对象类,应该codable必须采用NSCoding协议和实现它的方法。

考虑到可能的存档类型是很重要的,一个编码器支持。在OS X 10.2及以后版本,键控存档者优先。然而,你可能需要支持经典存档。,档案和序列化编程指南。

/**
 *  从文件中解析一个对象的时候就会调用这个方法
 *  通过xib或者storyboard创建UI控件就会调用这个方法
 */
- (id)initWithCoder:(NSCoder *)decoder
{
    if (self = [super initWithCoder:decoder]) {
        // 代码
    }
    return self;
}
要编码的对象,必须实现NSCoding协议。

@protocol NSCoding

-(void) encoderWithCoder:(NSCoder *) aCoder;

-(id) initWithCoder:(NSCoder *) aDecoder;

@end

当对象需要保存自身时-encoderWithCoder:方法被调用

当对象需要加载自身时-initWithCoder:方法被调用

作用:通过xib或者storyboard创建UI控件就会调用这个方法

5、initWithFrame: 
一般创建UI对象有两种方式。 
一种是通过nib,一种是通过代码。 
如果是通过代码创建,那么就会调用这个方法,进行frame的部署,还有控件的创建。但是在这个方法中创建控件并且设置尺寸的话,你会发现UI控件不会显示。为什么呢?因为initWithFrame:调用时,frame是0,没有尺寸的,所以根据这个frame设置UI控件的frame自然也为空。一般在这个方法中初始化UI控件。在layoutSubviews方法设置UI控件的frame。

/**
 *  通过代码创建控件的时候就会调用
 */
- (id)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]) {
        // 初始化UI控件
    }
    return self;
}

 
/**
 *  UI控件重新部署
 */
- (void)layoutSubviews{

[super layoutSubviews];
    // 设置UI控件的frame

}

OC--init,initialize,initWithCoder:,initWithFrame:各方法的区别和加载顺序的更多相关文章

  1. OC中重写set和get方法、懒加载

    在写OC程序的时候,在很多时候我们会用到重写set或者get方法,重写这两个方法大多是用于刷新数据,比如懒加载. 意思就是说当你去调用set或者get方法时,系统会去调用重写的get或者set方法,这 ...

  2. 'module' object has no attribute 'Thread'解决方法及模块加载顺序

    源码片段: class myThread(threading.Thread): def __init__(self, threadID, name, counter): threading.Threa ...

  3. init,initialize,initWithFrame,initWithCoder,awakeFromNib等区别

    1.init 与initialize 对于iOS程序,创建几个类对象,就会调用几次init.下面分别重写 举例如下: 创建一个Person类,分别重写initialize和init方法 #import ...

  4. initialize和init以及load方法的区别与使用以及什么时候调用

    initialize不是init initialize在这个类第一次被调用的时候比如[[class alloc]init]会调用一次initialize方法,不管创建多少次这个类,都只会调用一次这个方 ...

  5. 关于Cocos2d-x中init方法和onEnter方法的区别

    init()和onEnter()这两个方法都是写实例化对象的类(比如继承自Node的一些类等等)的时候用到的方法. 一般都是public类型下面的 bool init(); void onEnter( ...

  6. 李洪强iOS开发之OC[017]函数和方法的区别

    // //  main.m //  15 - 函数和对象的方法的区别 // //  Created by vic fan on 16/7/12. //  Copyright © 2016年 李洪强. ...

  7. 二.OC基础--1,对象的存储细节,2,#pragma mark指令,3,函数和对象方法的区别,4,对象和方法之间的关系 ,5.课堂习题

    1,对象的存储细节, 1. 当创建一个对象的时候:Person *p1 = [Person new],做了三件事情: 1,申请堆内存空间: 2,给实例变量初始化: 3,返回所申请空间的首地址; 2. ...

  8. oc中protocol、category和继承的区别

    OC中protocol.category和继承的区别以前还是有点迷糊,面试的时候说的有点混乱,现在结合一些资料总结一下. 利用继承,多态是一个很好的保持"对扩展开放.对更改封闭"( ...

  9. [BS-27] 创建NSURL的几个方法的区别

    创建NSURL的几个方法的区别     URL的基本格式 = 协议://主机地址/路径 URL和Path的区别 * URL:统一资源定位符,格式 “协议+主机名称+路径”   例如:[NSURL UR ...

随机推荐

  1. iOS 企业设备管理 补充中。。。

    公司的设备都有一个统一的管理方法,以前不太明白,今天看了一下资料. 这里解释了什么是设备管理 Profile Manager creates and distributes configuration ...

  2. Python3实现火车票查询工具

    Python 实现火车票查询工具 一. 实验介绍 通过python3实现一个简单的命令行版本的火车票查询工具,用实际中的例子会更感兴趣,不管怎么样,既练习了又可以自己使用. 1.  知识点: Pyth ...

  3. excel小技巧

    数据呈文本格式,怎么改成数字? 数据前有'号,如何去掉? 为什么数据格式在修改后需要再双击一下单元格才改过来了? 解决办法:你选中需要更改格式的那列              数据          ...

  4. axure rp8.0 序列号,亲测可以用

    转载自:https://zhidao.baidu.com/question/428326076480233092.html aaa 2GQrt5XHYY7SBK/4b22Gm4Dh8alaR0/0k3 ...

  5. 第二天--html

    <!DOCTYPE html><!--设置文档类型为标准的html5模型--><html>    <head>        <meta char ...

  6. [Android Pro] 精确记录和恢复ListView滑动位置

    reference to : http://blog.csdn.net/welovesunflower/article/details/7926512 工作中遇到一个需求,对ListView某一项操作 ...

  7. 【转】网络编程socket基本API详解

    转自:http://www.cnblogs.com/luxiaoxun/archive/2012/10/16/2725760.html socket socket是在应用层和传输层之间的一个抽象层,它 ...

  8. centos7.0 安装redis集群

    生产环境下redis基本上都是用的集群,毕竟单机版随时都可能挂掉,风险太大.这里我就来搭建一个基本的redis集群,功能够用但是还需要完善,当然如果有钱可以去阿里云买云数据库Redis版的,那个还是很 ...

  9. [图像]判断图片是PNG还是JPG格式

    typedef NS_ENUM(NSInteger, NSPUIImageType) { NSPUIImageType_JPEG, NSPUIImageType_PNG, NSPUIImageType ...

  10. Delphi容器类之---TList、TObjectList、TComponentList、TClassList

    转载自:http://blog.csdn.net/iseekcode/article/details/4922001 从Delphi5开始VCL中增加了新的Contnrs单元,单元中定义了8个新的类, ...