目录

Objective-C_09.@property @synthesize和id

一、@property @synthesize关键字

注意:这两个关键字是编译器特性,让xcode可以自动生成getter和setter的声明和实现。

(一)@property 关键字

@property关键字可以自动生成某个成员变量的setter和getter方法的声明 @property int age;

编译时遇到这一行,则自动扩展成下面两句:

1
2
- (void)setAge:(int)age;
- (int)age;

(二)@synthesize关键字

@synthesize关键字帮助生成成员变量的setter和getter方法的实现。 语法:@synthesize age=_age; 相当于下面的代码:

1
2
3
4
5
6
7
8
- voidsetAge:(int)age
{
  _age = age;
}
- (int)age
{
  return _age;
}

(三)关键字的使用和使用注意

类的声明部分:

1
2
3
4
5
6
@interface Person : NSObject

// 使用 @property 关键字实现 _age成员变量的 set 和get 方法的声明
@property int age;

@end

类的实现部分:

1
2
3
4
5
6
7
8
@implementation Person

// 使用 @synthesize 关键字实现 _age 成员变量的 set 和 get 方法的声明
@synthesize age = _age;
// 左边的 age 代表要把 @property int age 实现
// 右边的 _age 代表着访问 _age 这个成员变量

@end

测试程序:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
Person *p = [[Person alloc] init];
[p setAge:10];

// 使用点语法, 打印成员变量的值以验证
// 点语法的本质是调用 set 和 get 方法
NSLog(@"age = %d", p.age);

[p setAge:22];

NSLog(@"age = %d", p.age);

// 打印结果
2016-07-30 00:00:17.353 test[28024:6636559] age = 10
2016-07-30 00:00:17.353 test[28024:6636559] age = 22

新版本中:

类的声明部分:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
@interface Person : NSObject
{
    // 类的成员变量, 这样的方式默认为 protected
    // 如果这里不写成员变量, 那么会自动生成, 但是 private 的
    int _age;
    double _weight;
    double _height;
    NSString *_name;
}
// 使用 @property 关键字生成成员变量的 set 和get 方法的声明和实现
@property int age;
@property double weight;
@property double height;
@property NSString *name;

@end

类的实现部分:

1
2
3
4
5
@implementation Person

// 从 xcode4.4 以后, @property 关键字独揽了三个功能

@end

测试程序:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// person 类型的指针指向一个 person 类型创建的对象
   Person *p = [[Person alloc] init];

   // 使用点语法为 _age 成员变量赋值
   p.age = 22;
   // 使用set方法为成员变量赋值
   [p setHeight:169];
   [p setWeight:50];
   [p setName:@"yongyuan"];

   // 使用点语法,本质是调用 get 方法
   NSLog(@"age = %d, height = %f, weight = %f, name = %@", p.age, p.height, p.weight, p.name);

   // 打印结果
   2016-07-30 00:09:49.008 test[28138:6663258] age = 22, height = 169.000000, weight = 50.000000, name = yongyuan
  1. 在老式的代码中,@property只能写在@interface @end中,@synthesize只能写在@implementation @end中,自从xcode 4.4 后,@property就独揽了@property@synthesize的功能。
  2. @property int age;这句话完成了3个功能,注意:这种方式生成的成员变量是private的:
    1. 生成_age成员变量的getset方法的声明;
    2. 生成_age成员变量setget方法的实现;
    3. 生成一个_age的成员变量。
  3. 可以通过在{}中加上int _age;显示的声明_ageprotected的。
  4. 原则:getset方法同变量一样,如果你自己定义了,那么就使用你已经定义的,如果没有定义,那么就自动生成一个。
  5. 手动实现:
    1. 如果手动实现了set方法,那么编译器就只生成get方法和成员变量;
    2. 如果手动实现了get方法,那么编译器就只生成set方法和成员变量;
    3. 如果setget方法都是手动实现的,那么编译器将不会生成成员变量。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
@interface Dog : NSObject
{
    // 可以省略这里的成员变量
    int _age;
}

// 使用 @property 关键字生成成员变量 set 和 get 方法的声明和实现
@property int age;

@end

@implementation Dog

// 自定义的成员变量的放回方法

- (int)age
{
  return 10;
}
@end

 Dog *d = [[Dog alloc] init];

 // 使用点语法调用 set 方法设置 ahe 的值为5
 // 在这里调用 set 方法, 因为没有, 所以编译器在编译时自动生成了
 d.age = 5;

 // 因为自己定义了 get 方法, 所以 xcode 尊重用户的选择, 请注意输出结果

 NSLog(@"%d", d.age);

// 打印结果
2016-07-30 00:19:52.004 test[28251:6708346] 10

二、id

id 是一种类型,万能指针,能够指向操作任何的对象。

注意:在id的定义中,已经包好了*号。id指针只能指向 OC 的对象。

id 类型的定义

1
2
3
4
Typedef struct objc object
{
    Class isa;
} *id;

局限性:调用一个不存在的方法,编译器会马上报错。