#ios
栗子:
![[Pasted image 20241024101001.png]]
在 Objective-C 中,调用 alloc 时通常需要紧接着调用 init(或它的变种 initWith...),因为 alloc 只是为对象分配内存,而 init 负责进行初始化设置和状态的配置。这两个方法通常是配套使用的。
alloc 和 init 需要一起使用alloc:仅分配内存给对象,并设置对象的基本结构(如引用计数)。在这个阶段,尚未初始化对象的状态。
init:初始化对象的状态,设置对象的内部数据。对象在调用 init 后,才能进入一个可用的状态。
因此,调用 alloc 之后,必须调用 init 或其他具体的初始化方法才能得到一个完全可用的对象。
通常,我们会这样使用:
MyClass *object = [[MyClass alloc] init];
alloc 分配内存,init 对对象进行初始化,这种组合通常会确保创建的对象是有效的。
init?每当你通过 alloc 创建一个新对象时,通常都需要调用 init 或者某个特定的初始化方法,例如 initWithName: 或 initWithFrame: 等等。
alloc + init最常见的场景是调用无参的 init 方法进行初始化。许多类的 init 方法负责设置对象的默认状态:
MyClass *object = [[MyClass alloc] init];
alloc + initWith...有时类提供了自定义的初始化方法,如 initWith...,它们需要特定的参数来进行对象的初始化。比如:
MyClass *object = [[MyClass alloc] initWithName:@"Example"];
在这种情况下,initWithName: 方法会初始化对象的内部状态,比如名称属性。
init 方法的继承和重写如果你创建了一个自定义类并希望定义自己的初始化逻辑,可以通过重写 init 方法来完成:
- (instancetype)init {
self = [super init]; // 调用父类的初始化方法
if (self) {
// 自定义初始化逻辑
_name = @"DefaultName";
}
return self;
}
在这里,[super init] 调用父类的 init 方法来确保父类部分被正确初始化。之后,你可以添加自定义逻辑来设置当前类的属性或状态。
init?一些类提供了工厂方法来创建对象,它们通常隐藏了 alloc 和 init 的细节。在这种情况下,你不需要手动调用 alloc 和 init。
例如,NSString 类的 stringWithString: 方法:
NSString *string = [NSString stringWithString:@"Hello"];
这个工厂方法内部会完成对象的创建和初始化,因此你不需要显式地调用 alloc 和 init。
同理,其他常用的类也提供类似的方法,比如:
NSArray *array = [NSArray arrayWithObjects:@"A", @"B", @"C", nil];
当你接收到一个已经初始化的对象时,你不需要再次调用 init。例如,如果你通过其他方法或函数获得了对象,它已经是完全可用的了。
init 方法返回 nil如果对象初始化失败(例如资源分配不成功),init 方法可能会返回 nil。因此,初始化对象时,最好检查返回值:
MyClass *object = [[MyClass alloc] init];
if (object) {
// 成功初始化
} else {
// 初始化失败,处理错误
}
alloc 但不 init 的错误示例如果你只调用 alloc 而不调用 init,对象没有被正确初始化,可能导致不可预见的错误。比如:
MyClass *object = [MyClass alloc]; // 忘记了调用 init
alloc 分配内存,init 初始化对象。调用 alloc 后,通常必须调用 init 或其他初始化方法。init 方法。stringWithString:)时不需要显式调用 alloc 和 init,这些方法已经处理了对象的初始化。alloc 而不 init 的情况,否则对象可能未初始化,无法安全使用。