iOS--@protocol 和 category 中如何使用 @property
2018-01-23 10:01
507 查看
1、category中使用@property
首先需要明确的一点是,在category中不能添加实例变量。在我之前的一篇博客中有讲到,使用@property可以让编译器自动帮我们生成实例变量的setter/getter方法
现在我们先在类中添加一个实例变量
//in .h @interface MyClass : NSObject{ NSString _name; } @end //in .m @implementation MyClass{ //NSString * _name; } @end
注意这里把实例变量声明在头文件里和实现文件里会有所不同
实例变量在类的声明处声明,若它的访问权限不是@private,那它是可以被子类继承的,并且可以被其他类访问(若访问权限是@public)
实例变量在类的实现处声明和在extension中声明,该实例变量是私有的,即使加@public访问权限也是私有的,不可以被子类继承,当然在category中也不能访问
然后创建一个类别
//in .h #import "MyClass.h" @interface MyClass (Extension) @property(nonatomic,copy)NSString * name; @end //in .m #import "MyClass+Extension.h" @implementation MyClass (Extension) //@synthesize name = _name; @end
编译器给出了警告
大意是说属性name需要提供setter/getter方法,也就是说现在编译器不能自动给我们生成setter和getter方法了
添加一句@synthesize name = _name;也是不行的
此时就需要我们自己写setter/getter方法了
//in category.m #import "MyClass+Extension.h" @implementation MyClass (Extension) - (void)setName:(NSString *)name{ _name = name; } - (NSString *)name{ return _name; } @end
如果之前我们将实例变量声明在类声明部分的话,这样执行一发,就没问题了。但是很多时候,我们不希望去修改已经写好的类,而且定义的实例变量在类实现部分。那么此时在category中我们就不能直接访问到该实例变量了,例如
//in .h @interface MyClass : NSObject @end //in .m #import "MyClass.h" @implementation MyClass{ NSString * _name; } @end
像这种情况,我们就需要利用到runtime了。
objc_setAssociatedObject 相当于 setValue:forKey 进行关联value对象 objc_getAssociatedObject 用来读取对象 objc_AssociationPolicy 属性 是设定该value在object内的属性,即 assgin, (retain,nonatomic)...等 objc_removeAssociatedObjects 函数来移除一个关联对象,或者使用objc_setAssociatedObject函数将key指定的关联对象设置为nil。
我们可以使用这四个函数,在category中任意添加实例变量。例如之前的就可以写成
#import "MyClass+Extension.h" #import <objc/runtime.h> @implementation MyClass (Extension) - (void)setName:(NSString *)name{ objc_setAssociatedObject(self,@selector(name),name,OBJC_ASSOCIATION_COPY_NONATOMIC); } - (NSString *)name{ NSString *n = objc_getAssociatedObject(self, @selector(name)); return n; } @end
就相当于在类中添加了一个名为name的实例变量,与_name不同。
当然使用这种方式并不比使用@property管理内存方便。
2.在@protocol中使用@property
在@protocol中使用@property在编译阶段,编译器会自动帮我们加上setter/getter的声明,但是实现还是需要采用该协议的类去写。因此在协议中使用@property主要是希望采用该协议的类能够实现该属性相关文章推荐
- @protocol和category 中如何使用@property (协议和分类中如何使用@property属性)
- @protocol 和 category 中如何使用 @property
- @protocol 和 category 中如何使用 @property
- 【iOS】Xcode中如何新建Category、Empty File、Protocol、Extension
- 在category和protocol中如何实现@property
- @protocol和category中如何使用@property?
- ios开发——日常之在Xcode6 后如何创建类目和延展(category&extension&protocol)
- iOS使用Category添加@property变量
- 在iOS中如何使用汇编语言
- 如何使用iOS手势UIGestureRecognizer
- iOS开发:如何使用iOS手势UIGestureRecognizer
- 在iOS下使用google protocol buffer
- 如何使用subversion管理iOS源代码 推荐
- 如何设置IOS project构建所使用的 Base SDK 和 iOS Deployment Target版本
- 如何写一个使用Web Service的IOS应用
- 如何在iOS中使用Block
- iOS开发:如何使用iOS手势UIGestureRecognizer
- 发布iOS应用全攻略(二)——如何使用iOS开发者授权以及如何申请证书
- [iOS开发必备知识之] Category & Protocol
- 在iOS中使用Google Protocol Buffer