浅学Objective-C 初始化方法

本文介绍了Objective-C中初始化方法的概念,包括指定初始化方法和便利初始化方法的定义与区别。遵循苹果文档,文章详细阐述了初始化方法的基本步骤,强调了调用父类初始化方法的重要性,并列举了初始化方法的几条关键规则。同时,通过具体示例说明了初始化方法的调用顺序,帮助读者深入理解对象的初始化过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

一开始学习objective—C,我对于对象的初始化知之甚少,存在一定的概念混淆,在这里做个梳理和记录,希望对同样困扰的人有所帮助。

初始化方法

初始化方法用于初始化当前对象、实例变量。

苹果文档给出的对象生成图:
苹果文档给出的图片每个初始化方法的方法名都以英文单词init开头,会带参数,同其他的实例方法无异。在Objective-C中的命名规范无需重复,必须严格遵守,忽视命名约定会产生超过预期的错误。

实现初始化方法的基本步骤如下:

  1. 调用父类初始化方法,即父类的指定初始化方法,并检查其返回值。(使用保留字super指定超类。)若返回值不为nil,则可以继续初始化。
  2. 对象的实例变量赋值。
  3. 返回初始化对象,或者如果初始化不成功,则返回nil。

    举个例子1,指定初始化方法:

- (id)init {
//1.调用父类初始化方法,也是指定初始化方法
            self = [super init];
            if (self ) { 
//2.实例变量赋值
                _date = [[NSDate date] retain];
            }
//3.返回初始化对象
        return self;
}

指定初始化方法

指定初始化方法的作用是确保对象的每个实例变量都处在一个有效(valid)的状态,即初始化后的对象发送信息时,输出的结果是可预期的。

同一个类会因不同的需求,会提供一个以上的初始化方法,但无论其有多少个初始化方法,必须有一个指定初始化方法(designated initializer)。
指定初始化方法的参数通常和最重要、最常用的实例变量相对应,确保继承的程序能够正确地初始化所有实例变量。

初始化方法的几个规则

  • 1.子类会继承父类所有的初始化方法,也可以为类新加入任意数量的初始化方法
  • 2.每个类都要选定一个指定初始化方法,其余为便利初始化方法
  • 3.在执行其他便利初始化工作之前,必须先用指定初始化方法调用父类的指定初始化方法([super init…])(直接或间接),只有指定初始化函数才有资格调用父类的指定初始化方法
  • 4.便利初始化方法要调用指定初始化方法([self init…])(直接或间接),而且便利初始化函数只能调用自己类中的其他初始化方法
  • 5.如果某个类所声明的指定初始化方法与其父类的不同,就必须覆盖父类的指定初始化方法并调用新的指定初始化方法(直接或间接)
  • 6.如果某个类提供了一个或者多个指定初始化方法,就必须实现其父类的所有的指定初始化方法

    如果违背上面任意一条规则,编译时就会报警告。苹果官方关于初始化规则的图较为形象描述:苹果官方关于初始化规则的图
    举个例子1.TestClass

@interface TestClass
    NSString *_itemName;
    NSString *_serialNumber;
    int _valueInDollars;
    NSDate *_dateCreated;
@end
@implementation TestClass
 - (instancetype)initWithItemName:(NSString *)name
                  valueInDollars:(int)value
                    serialNumber:(NSString *)sNumber
{
// 指定初始化方法,必须先调用父类的指定初始化方法
// 调用父类初始化方法
    self = [super init];
// 初始化是否成功?
    if (self) {
// 实例变量初始化赋值
         _itemName = name;
         _serialNumber = sNumber;
         _valueInDollars = value;
         _dateCreated = [[NSDate alloc] init];
    }
// 返回初始化对象
    return self;
}
 - (instancetype)initWithItemName:(NSString *)name
{
//便利初始化方法
//便利初始化函数只能调用自己类中的其他初始化方法
    return [self initWithItemName:name
                   valueInDollars:0
                     serialNumber:@""];
}
 - (instancetype)init
{
//便利初始化方法
//便利初始化函数只能调用自己类中的其他初始化方法
    return [self initWithItemName:@"Item"];
}
@end

规则总结就两条:
- 便利初始化方法实现只能而且必须调用自己类中的其他初始化方法
- 指定初始化方法实现才有资格而且必须调用父类的指定初始化方法
例子1 中,执行newObject = [TestClass alloc]int],初始化调用的过程应该为:TestClass:init -> TestClass:initWithItemName -> TestClass:initWithItemName:valueIndollars:serialNumber -> superClass:init;
例子1初始化调用过程:这里写图片描述而初始化方法的实际执行顺序恰好相反,这个逻辑很重要。
对象的创建过程是从根类到子类依次初始化所有成员变量。苹果文档给出关于多个初始化方法的对象初始化过程:
苹果文档给出关于多个初始化方法的对象初始化过程

若有不足,请大家多多指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值