一、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日志相同,同时为: