一、property

合成存取器: 

@property的格式:

 1 @property (修饰列表) 变量类型 变量名; 

 

Xcode4.4之前:

@property使编译器自定生成set/get方法声明。

@synthesize自动生成set/get方法的实现

@synthesize还会自动生成私有成员变量

 

Xcode4.4以后:

不用再写@synthesize,编译器通过@property就能给我们生成set/get方法的声明和实现,默认生成成员变量:_propertyName

用@property生成的成员变量是私有的。

 当我们想改变默认的成员变量名时,@synthesize age = newName;‘

如果子类想访问父类的成员变量,

1、通过set/get方法

2、显示的声明成员变量

**进入正题**

首先声明:

category和protocol可以添加方法

category 和 protocol中可以添加@property 关键字

二、关于protocol中的property

在protocol中添加property时,其实就是声明了 getter 和 setter 方法,在实现这个protocol协议的类中,我们要自己手动添加实例变量,并且需要实现setter/getter方法

伪代码:

main.m

1 Student *student = [[Student alloc] init];
2         
3 student.name = @"彭爸爸";
4         
5 NSLog(@"%@", student.name);
6         

person.h

设置协议,与其中的property

 1 //
 2 //  Person.h
 3 //  类别 和 协议
 4 //
 5 //  Created by ma c on 16/5/19.
 6 //  Copyright © 2016年 彭盛凇. All rights reserved.
 7 //
 8 
 9 #import <Foundation/Foundation.h>
10 
11 @protocol personDelegate <NSObject>
12 
13 @property (nonatomic, copy) NSString *name;
14 
15 @end
16 
17 @interface Person : NSObject
18 
19 @end

student.h

生成成员变量,_name

 1 //
 2 //  PersonSon.h
 3 //  类别 和 协议
 4 //
 5 //  Created by ma c on 16/5/19.
 6 //  Copyright © 2016年 彭盛凇. All rights reserved.
 7 //
 8 
 9 #import <Foundation/Foundation.h>
10 #import "Person.h"
11 
12 @interface Student : NSObject <personDelegate>
13 {
14     //***声明成员变量***
15      NSString *_name;
16 }
17 
18 
19 @end

student.m

这里写了两种方法,一种是自动实现setter/gerter,一种为手动setter/gerter

 1 //
 2 //  PersonSon.m
 3 //  类别 和 协议
 4 //
 5 //  Created by ma c on 16/5/19.
 6 //  Copyright © 2016年 彭盛凇. All rights reserved.
 7 //
 8 
 9 #import "Student.h"
10 
11 @implementation Student
12 
13 //------------------自动----------------------//
14 //@synthesize 
15 //
16 //编译器期间,让编译器自动生成getter/setter方法。
17 //
18 //当有自定义的存或取方法时,自定义会屏蔽自动生成该方法
19 
20 //自动生成setter/getter方法
21 
22 //@synthesize name;
23 
24 
25 
26 //------------------手动----------------------//
27 
28 //@dynamic
29 //
30 //告诉编译器,不自动生成getter/setter方法,避免编译期间产生警告
31 //
32 //然后由自己实现存取方法
33 
34 //实现Person中定义的属性name的set方法
35 - (void)setName:(NSString *)name {
36     _name = name;
37     
38 }
39 
40 //实现Person中定义的属性name的get方法
41 - (NSString *)name {
42     return _name;
43 }
44 
45 @end

打印Log日志为:

说明成功实现property的基本功能,并可以实现赋值与取值操作

 

三、category中的property

 

在category中添加property时, 在@implentation添加 getter 和 setter方法时, 由于category不能添加实例变量

 

1)使用临时全局变量来替代成员变量

首先声明:Person没有name属性

main.m

导入头文件:

#import "Person+Extension.h"

1 Person *person = [[Person alloc] init];
2         
3 person.name = @"peng";
4         
5 NSLog(@"%@", person.name);

Person+Extension.h

 1 //
 2 //  Person+Extension.h
 3 //  类别 和 协议
 4 //
 5 //  Created by ma c on 16/5/19.
 6 //  Copyright © 2016年 彭盛凇. All rights reserved.
 7 //
 8 
 9 #import "Person.h"
10 
11 @interface Person (Extension)
12 
13 @property (nonatomic, strong) NSString *name;
14 
15 @end

Person+Extension.m

 1 //
 2 //  Person+Extension.m
 3 //  类别 和 协议
 4 //
 5 //  Created by ma c on 16/5/19.
 6 //  Copyright © 2016年 彭盛凇. All rights reserved.
 7 //
 8 
 9 #import "Person+Extension.h"
10 #import <objc/runtime.h>
11 
12 //***临时变量***
13 static NSString *_name;
14 
15 @implementation Person (Extension)
16 
17 - (void)setName:(NSString *)name {
18     _name = name;
19 }
20 
21 - (NSString *)name {
22     return _name;
23 }
24 @end

2)使用runtime 关联对象 实现成员变量

除了Person+Extension.m 其他与 第一种方法一致

runtime Person+Extension.m

 1 @implementation Person (Extension)
 2 
 3 - (void)setName:(NSString *)name{
 4     objc_setAssociatedObject(self,@selector(name),name,OBJC_ASSOCIATION_RETAIN_NONATOMIC);
 5 }
 6 
 7 - (NSString *)name{
 8     
 9     NSString *n = objc_getAssociatedObject(self, @selector(name));
10     return n;
11 }

两种方式打印Log日志相同,同时为: