Chinaunix首页 | 论坛 | 博客
  • 博客访问: 157904
  • 博文数量: 17
  • 博客积分: 497
  • 博客等级: 下士
  • 技术积分: 187
  • 用 户 组: 普通用户
  • 注册时间: 2011-11-02 18:40
文章分类

全部博文(17)

文章存档

2012年(8)

2011年(9)

分类: 嵌入式

2012-03-15 15:26:30

Objective-C边学边记:对象初始化
2010年11月08日 13:54 来源:小糊涂闲博客 作者:小糊涂闲 编辑:景保玉

  【IT168技术】到目前为止,我们已经学习了两种创建新对象的方法:[类名 new] 和 [[类名 alloc] init]。这两种方法是等价的,不过Cocoa的惯例是使用后者。

  有些语言(如C++和Java)使用构造函数在单次操作中执行对象的分配和初始化。Objective-C将这两种操作拆分为两个明确的步骤:分配和初始化。

  分配(allocation):向某个类发送alloc消息的结果就是为该类分配一块足够大的内存,以存放该类的全部实例变量。同时,alloc方法还顺便将这块内存区域全部初始化为0。

  初始化(initialization)从操作系统取得一块内存,准备用于存储对象。init方法几乎总是返回它们正在初始化的对象。应该像下面这样嵌套调用alloc和init方法:

  Car *car = [[Car alloc] init];

  而不是像下面这样:

  Car *car = [Car alloc];

        [car init];

  这种嵌套调用技术非常重要,因为初始化方法返回的对象可能与分配的对象不同(见NSString章节末尾的类簇)。

  编写初始化方法:

- (id) inti
{
    
if (self = [super init])
    {
        
// …. 进行初始化
    )

    return (
set);
}

 

  便利初始化函数(convenience initializer),是用来完成某些额外工作的初始化方法,可以减少你自己完成这些工作的麻烦。例如:

    // 返回一个空字符串
    NSString 
*emptyString = [[NSString alloc] init];
    
    
// 按格式返回字符串
    NSString 
*string = [[NSString alloc] 
                initWithFormat:@
"%d or %d"25 124];
    
// 打开指定路径上的文本文件,读取文件内容
    NSString 
*file = [[NSString alloc] 
              initWithContentsOfFile: @
"/tmp/words.txt"];

 

  为了初始化的便利性,一个类可能有多个初始化方法。为了正确完成实例化并且子类继承时不出现问题,请明确一个“指定初始化函数”(designated initializer)。

  类中的某个初始化方法被指派为指定初始化函数。该类的所有初始化方法使用指定初始化函数执行初始化操作。子类使用其超类的指定初始化函数实现超类的初始化。通常,接受参数最多的初始化方法最终成为指定初始化函数。

  Example:

InitExample.h 
1 //
2  //  InitExample.h
3  //  示例类的初始化,添加指定初始化函数
4  //
5  //  Created by Elf Sundae on 10/26/10.
6  //  Copyright 2010 Elf.Sundae(at)Gmail.com . All rights reserved.
7  //
8  
9 #import <Foundation/Foundation.h>
10 
11 
12 @interface InitExample : NSObject 
13 {
14     NSString *firstName;
15     NSString *lastName;
16     NSString *fullName;
17 }
18 
19  - (void) setFirstName: (NSString *) firstName;
20  - (NSString *) firstName;
21 
22 - (void) setLastName: (NSString *) lastName;
23 - (NSString *) lastName;
24 
25 - (NSString *) fullName;
26 
27 - (id) initWithFirstName: (NSString *) firstName;
28 - (id) initWithLastName: (NSString *) lastName;
29 - (id) initWithFirstName: (NSString *) firstName lastName:(NSString *) lastName;
30 
31 @end
  InitExample.m 
1 //
2 //  InitExample.m
3 //  Initializer
4 //
5 //  Created by Elf Sundae on 10/26/10.
6 //  Copyright 2010 Elf.Sundae(at)Gmail.com . All rights reserved.
7 //
8 
9 #import "InitExample.h"
10 
11 
12 @implementation InitExample
13 
14 // *************************************************
15 // 属性访问方法
16 - (void) setFirstName: (NSString *) m_firstName
17 {
18     firstName = m_firstName;
19 }
20 - (NSString *) firstName
21 {
22     return firstName;
23 }
24 
25 - (void) setLastName: (NSString *) m_lastName
26 {
27     lastName = m_lastName;
28 }
29 - (NSString *) lastName
30 {
31     return lastName;
32 }
33 
34 - (NSString *) fullName;
35 {
36     return [NSString stringWithFormat:@"%@ %@",firstName,lastName];
37 }
38 
39 // *************************************************
40 // 初始化方法
41 
42 // 指定初始化函数(designated initializer)
43 - (id) initWithFirstName: (NSString *) m_firstName 
44         lastName:(NSString *) m_lastName
45 {
46     if (self = [super init])
47     {
48         firstName = m_firstName;
49         lastName = m_lastName;
50     }
51     return self;
52 }
53 
54 - (id) initWithFirstName: (NSString *) m_firstName
55 {
56     if (self = [self initWithFirstName:m_firstName 
57                   lastName:@"NoLastName"]){
58         
59     }
60     return self;
61 }
62 - (id) initWithLastName: (NSString *) m_lastName
63 {
64     if (self = [self initWithFirstName:@"NoFirstName" 
65                   lastName:m_lastName]){
66         
67     }
68     return self;
69 }
70 
71 - (id) init 
72 {
73     if (self = [self initWithFirstName:@"NoFirstName" 
74                   lastName:@"NoLastName"]){
75         
76     }
77     return self;
78 }
79 
80 @end
  SubClass.h 
1 //
2 //  SubClass.h
3 //  示例子类的初始化
4 //
5 //  Created by Elf Sundae on 10/26/10.
6 //  Copyright 2010 Elf.Sundae(at)Gmail.com . All rights reserved.
7 //
8 
9 #import <Foundation/Foundation.h>
10 #import "InitExample.h"
11 
12 @interface SubClass : InitExample
13 {
14     int age;
15 }
16 
17 - (void) setAge : (int) age;
18 - (int) age;
19 
20 - (id) initWithFirstName: (NSString *) m_firstName
21         lastName: (NSString *) m_lastName
22              age: (int) m_age;
23 
24 - (id) initWithAge: (int) age;
25 
26 
27 @end
  SubClass.m 
1 //
2 //  SubClass.m
3 //  Initializer
4 //
5 //  Created by Elf Sundae on 10/26/10.
6 //  Copyright 2010 Elf.Sundae(at)Gmail.com . All rights reserved.
7 //
8 
9 #import "SubClass.h"
10 
11 
12 @implementation SubClass
13 
14 - (void) setAge:(int)m_age
15 {
16     age = m_age;
17 }
18 
19 - (int) age
20 {
21     return age;
22 }
23 
24 - (NSString *) description
25 {
26     return [NSString stringWithFormat:@"I am %@ ,and I'm %d years old.",
27         self.fullName,self.age];
28     
29 }
30 
31 // 指定初始化函数
32 - (id) initWithFirstName: (NSString *) m_firstName
33         lastName: (NSString *) m_lastName
34              age: (int) m_age
35 {
36     if (self = [super initWithFirstName:m_firstName
37                    lastName:m_lastName])
38     {
39         age = m_age;
40     }
41     return self;
42 }
43 
44 // 重写父类的指定初始化函数
45 - (id) initWithFirstName:(NSString *)m_firstName 
46         lastName:(NSString *)m_lastName
47 {
48     // age 默认设为0
49     if (self = [self initWithFirstName:m_firstName 
50                   lastName:m_lastName
51                        age:0])
52     {
53     }
54     return self;
55 }
56 
57 - (id) initWithAge:(int)m_age
58 {
59     if (self = [super init])
60     {
61         age = m_age;
62     }
63     return self;
64 }
65 
66 
67 
68 
69 - (id) init
70 {
71     // age 默认设为0
72     if (self = [self initWithAge:0])
73     {
74     }
75     return self;
76 }
77 
78 @end
79 
  main 
1 #import <Foundation/Foundation.h>
2 #import "InitExample.h"
3 #import "SubClass.h"
4 
5 int main (int argc, const char * argv[]) {
6     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
7     
8     InitExample *myName = [[InitExample alloc] init];
9     NSLog(@"%@",[myName fullName]);
10     
11     InitExample *myName1 = [[InitExample alloc] initWithFirstName:@"Elf"];
12     NSLog(@"%@",[myName1 fullName]);
13     
14     InitExample *myName2 = [[InitExample alloc] initWithLastName:@"Sundae"];
15     NSLog(@"%@",[myName2 fullName]);
16     
17     InitExample *myName3 =  [[InitExample alloc] initWithFirstName:@"Elf"
18                                   lastName:@"Sundae"];
19     NSLog(@"%@",[myName3 fullName]);
20     
21     // 子类
22     SubClass *mySubClass = [[SubClass alloc] initWithAge:22];
23     NSLog(@"%@",mySubClass);
24     
25     SubClass *mySubClass1 = [[SubClass alloc] initWithFirstName:@"Elf"];
26     NSLog(@"%@",mySubClass1);
27     
28     SubClass *mySubClass2 = [[SubClass alloc] initWithFirstName:@"Elf"
29                                lastName:@"Sundae"];
30     NSLog(@"%@",mySubClass2);
31     
32     SubClass *mySubClass3 = [[SubClass alloc] initWithFirstName:@"Elf"
33                                lastName:@"Sundae" 
34                                 age:22];
35     NSLog(@"%@",mySubClass3);
36     
37     SubClass *mySubClass4 = [[SubClass alloc] initWithLastName:@"Sundae"];
38     NSLog(@"%@",mySubClass4);
39         
40     [pool drain];
41     return 0;
42 }

       总结:
        在Cocoa中,分配和初始化是两个分离的操作:来自NSObject的类方法alloc为对象分配一块内存区域并将其清零,实例方法init用于获得一个对象并使其运行。
        一个类可以拥有多个初始化方法。这些初始化方法通常是便利方法,可以更容易地实现你希望的对象配置方式。你可以从这些初始化方法中选择一个作为指定初始化函数。所有其他初始化方法应该按照指定初始化函数的形式编写。
        在你自己的初始化方法中,需要调用自己的指定初始化函数或者超类的指定初始化函数。一定要将超类的初始化函数的值赋给self对象,并返回你自己的初始化方法的值。超类可能返回一个完全不同的对象。

阅读(6982) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~