OC--init,initialize,initWithCoder:,initWithFrame:各方法的区别和加载顺序
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
#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]);
}
}
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---init4、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;
}@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:各方法的区别和加载顺序的更多相关文章
- OC中重写set和get方法、懒加载
在写OC程序的时候,在很多时候我们会用到重写set或者get方法,重写这两个方法大多是用于刷新数据,比如懒加载. 意思就是说当你去调用set或者get方法时,系统会去调用重写的get或者set方法,这 ...
- 'module' object has no attribute 'Thread'解决方法及模块加载顺序
源码片段: class myThread(threading.Thread): def __init__(self, threadID, name, counter): threading.Threa ...
- init,initialize,initWithFrame,initWithCoder,awakeFromNib等区别
1.init 与initialize 对于iOS程序,创建几个类对象,就会调用几次init.下面分别重写 举例如下: 创建一个Person类,分别重写initialize和init方法 #import ...
- initialize和init以及load方法的区别与使用以及什么时候调用
initialize不是init initialize在这个类第一次被调用的时候比如[[class alloc]init]会调用一次initialize方法,不管创建多少次这个类,都只会调用一次这个方 ...
- 关于Cocos2d-x中init方法和onEnter方法的区别
init()和onEnter()这两个方法都是写实例化对象的类(比如继承自Node的一些类等等)的时候用到的方法. 一般都是public类型下面的 bool init(); void onEnter( ...
- 李洪强iOS开发之OC[017]函数和方法的区别
// // main.m // 15 - 函数和对象的方法的区别 // // Created by vic fan on 16/7/12. // Copyright © 2016年 李洪强. ...
- 二.OC基础--1,对象的存储细节,2,#pragma mark指令,3,函数和对象方法的区别,4,对象和方法之间的关系 ,5.课堂习题
1,对象的存储细节, 1. 当创建一个对象的时候:Person *p1 = [Person new],做了三件事情: 1,申请堆内存空间: 2,给实例变量初始化: 3,返回所申请空间的首地址; 2. ...
- oc中protocol、category和继承的区别
OC中protocol.category和继承的区别以前还是有点迷糊,面试的时候说的有点混乱,现在结合一些资料总结一下. 利用继承,多态是一个很好的保持"对扩展开放.对更改封闭"( ...
- [BS-27] 创建NSURL的几个方法的区别
创建NSURL的几个方法的区别 URL的基本格式 = 协议://主机地址/路径 URL和Path的区别 * URL:统一资源定位符,格式 “协议+主机名称+路径” 例如:[NSURL UR ...
随机推荐
- C++编译期间字节序判断
当前常用的字节序一般就两种,大端序和小端序. 下面列出四种字节序的表达方式.在对应平台下,内存布局为{0x,00,0x01,0x02,0x03}的四字节,表示为十六进制的值就如下面代码所示的. END ...
- erlang 虚机性能调优
erlang 默认启动参数更多的是针对电信平台实时特性,简单调整参数能很大程度降低CPU消耗,提高处理能力. 1. 关闭spin_wait 设置参数:+sbwt none 我上一篇文章提到:erlan ...
- Selenium Xpath Tutorials - Identifying xpath for element with examples to use in selenium
Xpath in selenium is close to must required. XPath is element locator and you need to provide xpath ...
- 遍历list、set、map和array
public static void main(String[] args) { /*1. List*/ ArrayList<Integer> list = new ArrayList&l ...
- <%@ page trimDirectiveWhitespaces="true" %>
我们经常会在JSP页面上使用: <%@ page trimDirectiveWhitespaces="true" %> 这个命令可以使jsp输出的html时去除多余的空 ...
- Android Studio上NDK/JNI开发环境问题
基础环境: 操作系统 —— Windows 7 Android Studio —— 1.5.1(android-studio-bundle-141.2456560-windows.exe) NDK — ...
- Pyqt 基础功能
总结Pyqt的基础知识 1. Pyqt 设置禁止最大化及禁止拖拽窗口大小 # PyQT禁止窗口最大化按钮: self.setWindowFlags(QtCore.Qt.WindowMinimizeB ...
- spfa模板
通过stl的queue实现的spfa(vector实现邻接表存图) 本模板没有考虑存在两点不连通的情况 如果需要判断则需要用到并查集或者遍历整个邻接表 #include<iostream> ...
- MySQL性能优化总结
一.MySQL的主要适用场景 1.Web网站系统 2.日志记录系统 3.数据仓库系统 4.嵌入式系统 二.MySQL架构图: 三.MySQL存储引擎概述 1)MyISAM存储引擎 MyISAM存储引擎 ...
- 安装Python环境时遇到的问题
问题描述:An error occurred during the installation of assembly 'Microsoft.VC90.MFC,version="9.0.210 ...