您的位置:首页 > 移动开发 > Objective-C

【IOS 开发学习总结-OC-15】objective-c面向对象之——对象初始化

2015-09-24 10:03 716 查看
创建对象有2种方法(本质是一样的,都是用 alloc 方法为对象分配内存空间)。

1.
[[类名 alloc]init];


2.
[类名 new];


为对象分配内存空间

我们知道无论创建哪个对象,总需要先调用该类的 alloc 类方法来分配内存,这个alloc 类方法来自 NSObject, 而所有的 objective-c 类都是NSObject的子类。所以,所有的类都可以调用 alloc 方法来进行分配空间。

调用某个类的alloc 方法方法时,系统完成的2件事情:

1. 系统为该类的所有实例变量分配内存空间

2. 将每个实例变量的内存空间都重置为”0”。这个0,是广义上的0——所有整型变量所在空间重置为0;所有浮点变量的重置为0.0;所有 BOOL型变量都重置为 NO;所有指针类型变量都重置为 nil。

仅仅分配内存空间的对象还不能使用,必须先对该对象执行初始化后才能使用。OC 中最常用的初始化方法来自 NSObject的 init,所以呢,所有的类都可以调用该方法进行初始化。

初始化方法与对象初始化

init方法只是完成最基本的初始化,对象的所有成员变量依然是0。实际的编程中,我们可以重写 init 方法,满足自定义处理代码的需要。

示例代码:

FKUser.h

#import <Foundation/Foundation.h>

@interface FKUser : NSObject
// 使用@property定义3个属性
@property (nonatomic , copy) NSString* name;
@property (nonatomic , assign) int age;
@property (nonatomic , copy) NSString* address;
@end


FKUser.m

#import "FKUser.h"

@implementation FKUser
@synthesize name;
@synthesize age;
@synthesize address;
// 重写init方法,完成自定义初始化
- (id) init
{
    // 调用父类的init方法执行初始化,将初始化得到的对象赋值给self对象
    // 如果self不为nil,表明父类init方法初始化成功
    if(self = [super init])
    {
        // 对该对象的name、age、address赋初始值
        self.name = @"孙悟空";
        self.age = 500;
        self.address = @"花果山,水帘洞";
    }
    return self;
}
@end


FKUserTest.m

#import "FKUser.h"

int main(int argc , char * argv[])
{
    @autoreleasepool{
        // 创建并初始化FKUser对象
        FKUser* user = [[FKUser alloc] init];
        // 访问FKUser对象的属性
        NSLog(@"user的name为%@" , user.name);
        NSLog(@"user的age为%d" , user.age);
        NSLog(@"user的address为%@" , user.address);
    }
}


编译运行后,结果为:

2015-09-24 13:54:11.596 923[6428:316945] user的name为孙悟空
2015-09-24 13:54:11.597 923[6428:316945] user的age为500
2015-09-24 13:54:11.598 923[6428:316945] user的address为花果山,水帘洞


说明:这里用到的 init 方法不是NSObject 提供的,是FKUser.m中提供的。

便利的初始化方法

实际中,我们会根据需要为 objective-c 类提供很多以 init 开头,并允许自带一些参数的便利的初始化方法。

示例代码:

FKCar.h

#import <Foundation/Foundation.h>

@interface FKCar : NSObject
// 使用@property定义3个属性
@property (nonatomic , copy) NSString* brand;
@property (nonatomic , copy) NSString* model;
@property (nonatomic , copy) NSString* color;
// 定义initWithBrand: model:方法,完成自定义初始化
- (id) initWithBrand:(NSString*) brand model:(NSString*) model;
// 定义initWithBrand: model: color:方法,完成自定义初始化
- (id) initWithBrand:(NSString*) brand model:(NSString*) model
    color:(NSString*) color;
@end


FKCar.m

#import "FKCar.h"

@implementation FKCar
@synthesize brand = _brand;
@synthesize model = _model;
@synthesize color = _color;
// 重写init方法,完成自定义初始化
- (id) init
{
    // 调用父类的init方法执行初始化,将初始化得到的对象赋值给self对象
    // 如果self不为nil,表明父类init方法初始化成功
    if(self = [super init])
    {
        // 对该对象的brand、model、color赋初始值
        self.brand = @"奥迪";
        self.model = @"Q5";
        self.color = @"黑色";
    }
    return self;
}
// 实现initWithBrand: model:方法,完成自定义初始化
- (id) initWithBrand:(NSString*) brand model:(NSString*) model
{
    // 调用父类的init方法执行初始化,将初始化得到的对象赋值给self对象
    // 如果self不为nil,表明父类init方法初始化成功
    if(self = [super init])
    {
        // 对该对象的brand、model、color赋初始值
        self.brand = brand;
        self.model = model;
        self.color = @"黑色";
    }
    return self;
}
// 实现initWithBrand: model: color:方法,完成自定义初始化
- (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


FKCarTest.m

#import "FKCar.h"

int main(int argc , char * argv[])
{
    @autoreleasepool{
        // 创建并初始化FKCar对象
        FKCar* car1 = [[FKCar alloc] init];
        // 访问car1对象的属性
        NSLog(@"car1的brand为%@" , car1.brand);
        NSLog(@"car1的model为%@" , car1.model);
        NSLog(@"car1的color为%@" , car1.color);
        // 创建并初始化FKCar对象
        FKCar* car2 = [[FKCar alloc] initWithBrand:@"奔驰"
            model:@"ML350"];
        // 访问car1对象的属性
        NSLog(@"car2的brand为%@" , car2.brand);
        NSLog(@"car2的model为%@" , car2.model);
        NSLog(@"car2的color为%@" , car2.color);
        // 创建并初始化FKCar对象
        FKCar* car3 = [[FKCar alloc] initWithBrand:@"宝马"
            model:@"X5" color:@"BLACK"];
        // 访问car1对象的属性
        NSLog(@"car3的brand为%@" , car3.brand);
        NSLog(@"car3的model为%@" , car3.model);
        NSLog(@"car3的color为%@" , car3.color);               
    }
}


编译运行后的结果:

2015-09-24 14:01:03.652 923[6499:322947] car1的brand为奥迪
2015-09-24 14:01:03.656 923[6499:322947] car1的model为Q5
2015-09-24 14:01:03.657 923[6499:322947] car1的color为黑色
2015-09-24 14:01:03.658 923[6499:322947] car2的brand为奔驰
2015-09-24 14:01:03.658 923[6499:322947] car2的model为ML350
2015-09-24 14:01:03.659 923[6499:322947] car2的color为黑色
2015-09-24 14:01:03.659 923[6499:322947] car3的brand为宝马
2015-09-24 14:01:03.660 923[6499:322947] car3的model为X5
2015-09-24 14:01:03.660 923[6499:322947] car3的color为BLACK


代码复用

知识切入:

值得一提的是上面例子中有很好的代码复用。如果系统中包含了过个初始化方法,其中一个初始化方法执行体中完全包含另一个初始化方法的执行体,这样就可以进行代码复用。




如上图,初始化方法B中完全包含了初始化A。此时就可以直接在初始化方法 B 中调用初始化方法,实现代码复用,就像上面的栗子中做的那样。

开发者重写初始化方法的模板

- (id) init
{
    // 调用父类的init方法执行初始化,将初始化得到的对象赋值给self对象
    // 如果self不为nil,表明父类init方法初始化成功
    if(self = [super init])
    {
        //执行初始化
    }
    return self;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: