一、@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
|
- (void)setAge:(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
|
- 在老式的代码中,
@property
只能写在@interface
@end
中,@synthesize
只能写在@implementation
@end
中,自从xcode 4.4 后,@property
就独揽了@property
和@synthesize
的功能。
@property int age;
这句话完成了3个功能,注意:这种方式生成的成员变量是private
的:
- 生成
_age
成员变量的get
和set
方法的声明;
- 生成
_age
成员变量set
和get
方法的实现;
- 生成一个
_age
的成员变量。
- 可以通过在{}中加上
int _age;
显示的声明_age
为protected
的。
- 原则:
get
和set
方法同变量一样,如果你自己定义了,那么就使用你已经定义的,如果没有定义,那么就自动生成一个。
- 手动实现:
- 如果手动实现了
set
方法,那么编译器就只生成get
方法和成员变量;
- 如果手动实现了
get
方法,那么编译器就只生成set
方法和成员变量;
- 如果
set
和get
方法都是手动实现的,那么编译器将不会生成成员变量。
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;
|
局限性:调用一个不存在的方法,编译器会马上报错。