码迷,mamicode.com
首页 > 其他好文 > 详细

OC基础-关于构造方法

时间:2015-08-09 20:55:18      阅读:114      评论:0      收藏:0      [点我收藏+]

标签:

一 init的疑惑

    init是OC的构造方法,也即是初始化方法。init常见于创建对象实例,假如现有Person这个类,新建一个Person对象实例时:

Person *person = [ [Person alloc] init];

    以上代码执行的时候,实际实现了以下三个过程:

  • 向Person类发送了alloc消息,在堆内存中创建了该类的对象

  • 对象收到init消息后,进行对象的初始化

  • 返回对象中堆内存中的地址,赋值给person指针变量

1 未重写init方法

    给对象分配内存空间后,需要初始化对象,才能使用该对象。但后来自己做了尝试,当给对象分配内存后,不初始化对象,还是可以操作对象中的实例变量和方法的:

// Person.h
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property NSString *name;
@property int age;
/** 测试方法*/
- (void)testMethod;
@end
// Person.m
#import "Person.h"
@implementation Person
- (void)testMethod {
    NSLog(@"This is test method.");
}
@end

    然后在main.m中创建对象来进行测试:

// main.m
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {   
        // 为Person对象申请内存空间,但未初始化 
        Person *person = [Person alloc];
        NSLog(@"\nperson: %@\nName: %@\nAge: %d",
              person, person.name, person.age);
        [person testMethod];
    }
    return 0;
}

    输出结果:

2015-08-08 23:50:23.223 OC-类的练习01[484:9197] 
person: <Person: 0x100206730>
Name: (null)
Age: 0
2015-08-08 23:50:23.224 OC-类的练习01[484:9197] This is test method.

2 重写init方法

    在以上代码的基础上,重写Person类的init方法:

// Person.m
#import Person.h
@implementation Person
- (void)testMethod {
    NSLog(@"This is test method.");
}

- (instancetype)init {
    if (self = [super init]) {
        _age = 1;
        _name = @"Test";
    }
    return self
}
@end

    再在main.m中添加测试代码:

// main.m
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {   
        // 为Person对象申请内存空间,但不初始化 
        Person *person = [Person alloc];
        NSLog(@"\nperson: %@\nName: %@\nAge: %d",
              person, person.name, person.age);
        [person testMethod];
        // 初始化对象
        person = [person init];
        NSLog(@"\nperson: %@\nName: %@\nAge: %d",
              person, person.name, person.age);
    }
    return 0;
}

    输出结果:

2015-08-09 09:55:19.059 OC-类的练习01[458:9440] 
person: <Person: 0x1001064f0>
Name: (null)
Age: 0
2015-08-09 09:55:19.060 OC-类的练习01[458:9440] This is test method.
2015-08-09 09:55:19.060 OC-类的练习01[458:9440] 
person: <Person: 0x1001064f0>
Name: Test
Age: 1

    个人理解是,在向Person类发送alloc消息创建了对象后,内存已经将实例变量设为了最原始的值,比如这里的Age默认0,Name默认null,并可以操作其对象方法。而在未重写init方法之前发送init消息时,Age和Name的值保持跟未初始化时一致。在重写了init方法之后,再发送init消息时,则按照重写方法来设置属性的初始值。

    不过很迷惑,这跟书上的说法不一致。《ios编程》原话:任何一个对象都必须在创建并且初始化后才能使用(page31)。在网上未能找到更详尽的解释,后续如有新的进展再做跟进。

二 定制自己的初始化方法

    默认的init方法不一定适用每个场景,有时需要定制自己的初始化方法。继续以Person类作扩展,在Person.h中声明initWithName:(NSString *)name Age:(int)age方法:

// Person.h
@interface Person : NSObject
    ...
/** 定制自己的初始化方法*/
- (instancetype)initWithName:(NSString *)name Age:(int)age;
@end

    并在Person.m中添加以下代码:

// Person.m
#import Person.h
@implementation Person
    ...
- (instancetype)initWithName:(NSString *)name Age:(int)age {
    if (self = [super init]) {
        _name = name;
        _age = age;
    }
    return self;
}
@end

    在main.m中删除之前的测试代码,直接采用自定义的初始化方法来创建对象:

// main.m
#import <Foundation/Foundation.h>
#import "Person.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // 采用自定义初始化方法创建对象 
        Person *person = [[Person alloc] initWithName:@"Tom Smith" Age:20];
        NSLog(@"\nName: %@\nAge: %d", person.name, person.age);    
    }
    return 0;
}

    输出结果:

2015-08-09 10:20:50.780 OC-类的练习01[471:13356] 
Name: Tom Smith
Age: 20

三 重写description方法

    description方法,其实类似于java中的toString方法。如果以“NSLog(@"%@", person);”的形式打印时,只会输出person对象的内存地址,重写该方法可以输出我们需要的信息:

// Person.m
@implementation Person
    ...
- (NSString *)description {
    return [[NSString alloc] initWithFormat:@"\nDescription\nName: %@\nAge: %d",
        _name, _age];
}
@end

    然后在main.m中直接打印:

// main.m
#import <Foundation/Foundation.h>
#import "Person.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // 采用自定义初始化方法创建对象 
        Person *person = [[Person alloc] initWithName:@"Tom Smith" Age:20];
        NSLog(@"%@", person);    
    }
    return 0;
}

    输出结果:

2015-08-09 10:41:50.242 OC-类的练习01[494:17251] 
Description
Name: Tom Smith
Age: 20

 

OC基础-关于构造方法

标签:

原文地址:http://my.oschina.net/ljunb/blog/489714

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!