OC对象初始化

Posted Billy Miracle

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OC对象初始化相关的知识,希望对你有一定的参考价值。

大家都知道两种基本的创建对象的语法:[[类名 alloc] init] 和[类名 new]。

为对象分配空间

alloc 类方法来自 NSObject,而所有的 OC 类都是 NSObject 的子类,因此,所有的类都可以调用 alloc 类方法来分配内存。当系统调用 alloc 类方法时,系统完成如下事情:

  1. 系统为该对象的所有实例变量分配内存空间
  2. 将每个实例变量的内存空间都重置为0

初始化方法与对象初始化

NSObject提供的init方法虽然可以完成初始化,但由于它只是完成最基本的初始化,因此,对象的所有成员变量依然为0。在实际的编程过程中,可以提供自己的init方法,这个init方法实际上就是重写NSObject的init方法。当重写init方法时,开发者可以加入任意的自定义处理代码对属性执行初始化。
示例:

//  FKUser.h
#import <Foundation/Foundation.h>

@interface FKUser : NSObject
@property (copy) NSString* name;
@property int age;
@property (copy) NSString* address;
@end
//  FKUser.m

#import "FKUser.h"

@implementation FKUser
-(id) init {
    if(self = [super init]) {
        self->_name = @"Peter";
        self->_age = 6;
        self->_address = @"China";
    }
    return self;
}
@end
//  main.m

#import "FKUser.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        FKUser* user = [[FKUser alloc] init];
        NSLog(@"%@ %d %@", user.name, user.age, user.address);
    }
    return 0;
}

上面main. h中的init方法已经不是NSObjective提供的了,而是FKUser.m提供的。

便利的初始化方法

前面的示例中,FKUser只是重写了init方法,总是固定的初始化,不能根据参数执行动态初始化,实际上还会根据业务需要,为OC类提供更多便利的初始化方法,这些初始化方法通常会以init开头,并允许自带一些参数。
示例:

//  FKCar.h

#import <Foundation/Foundation.h>

@interface FKCar : NSObject
@property (nonatomic , copy) NSString* brand;
@property (nonatomic , copy) NSString* model;
@property (nonatomic , copy) NSString* color;
-(id) initWithBrand:(NSString*)brand model:(NSString*)model;
-(id) initWithBrand:(NSString*)brand model:(NSString*)model color:(NSString*)color;

@end
//  FKCar.m

#import "FKCar.h"

@implementation FKCar
-(id) init {
    //调用父类的init方法执行初始化,将初始化得到的对象赋值给self对象
    //如果self不为nil,则表明父类的init方法初始化成功
    if(self = [super init]) {
        self->_brand = @"Audi";
        self->_model = @"RS4";
        self->_color = @"Blue";
    }
    return self;
}
-(id) initWithBrand:(NSString *)brand model:(NSString *)model {
    //调用父类的init方法执行初始化,将初始化得到的对象赋值给self对象
    //如果self不为nil,则表明父类的init方法初始化成功
    if(self = [super init]) {
        self->_brand = brand;
        self->_model = model;
        self->_color = @"Grey";
    }
    return self;
}
-(id) initWithBrand:(NSString *)brand model:(NSString *)model color:(NSString *)color {
    //调用本类的initWithBrand:model:方法执行初始化,将初始化得到的对象赋值给self对象
    //如果self不为nil,则表明initWithBrand:model:方法初始化成功
    if(self = [self initWithBrand:brand model:model]) {
        //对对象的_color赋初始值
        self->_color = color;
    }
    return self;
}
@end
//  main.m

#import "FKCar.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        FKCar* car1 = [[FKCar alloc] init];
        NSLog(@"car1的brand为%@",car1.brand);
        NSLog(@"car1的model为%@",car1.model);
        NSLog(@"car1的color为%@",car1.color);
        FKCar* car2 = [[FKCar alloc] initWithBrand:@"Mercedes" model:@"C63S"];
        NSLog(@"car2的brand为%@",car2.brand);
        NSLog(@"car2的model为%@",car2.model);
        NSLog(@"car2的color为%@",car2.color);
        FKCar* car3 = [[FKCar alloc] initWithBrand:@"BMW" model:@"M3" color:@"Green"];
        NSLog(@"car3的brand为%@",car3.brand);
        NSLog(@"car3的model为%@",car3.model);
        NSLog(@"car3的color为%@",car3.color);
    }
    return 0;
}

上面程序的[super init]先调用父类的init方法执行默认初始化。如果系统中包含了多个初始化方法,其中一个初始化方法执行体中完全包含另一个初始化方法的执行体,对于这种完全包含的情况(如下),就可以直接在初始化方法B中调用初始化方法A,这样就可以更好的进行代码复用。
在这里插入图片描述
通过使用这些便利的初始化方法,程序可以在创建对象时立即初始化对象的属性,避免对象创建完成后再设置对象的属性。

以上是关于OC对象初始化的主要内容,如果未能解决你的问题,请参考以下文章

oc42--引用计数器

oc知识点 初始化方法

OC对象初始化

浅谈OC对象初始化的三种姿势

OC中自定义init方法

OC基础--构造方法