之前在相关的OC书上看到的关于分类的说法是:只能增加方法,但是不能增加成员变量。
但是今天,在一个练习中,需要用到增加一个成员变量,于是写下了下列代码:(已提出来单独讲此问题)
NSObject+Test.h
#import <Foundation/Foundation.h>
@interface NSObject (Test)
@property (nonatomic,copy) NSString *str;
@end
NSObject+Test.m
#import "NSObject+Test.h"
@implementation NSObject (Test)
- (void)setStr:(NSString *)str {
NSLog(@"%@",str);
}
@end
(在别处已创建类对象,并调用setter方法赋值str)
结果这是可行的,没有error,只有warning,也打印成功了
Property 'str' requires method 'str' to be defined - use @dynamic or provide a method implementation in this category
查出来去除警告的方法:
http://stackoverflow.com/questions/2520889/objective-c-categories-can-i-add-a-property-for-a-method-not-in-my-category
在.m文件中加一行 @dynamic str
其实就是warning后面提醒我们的意思。
如何理解
@property在通常情况下,除了生成setter和getter方法以外,如果没有该成员变量还会生成成员变量。而在分类中,@property只是生成setter和getter方法(非readonly),
等价于声明了setter和getter方法
- (void)setStr:(NSString *)str;
- (NSString *)str;
添加这句话@dynamic str;是告诉编译器,setter和getter方法由用户自己实现,不自动生成。这里涉及一个动态绑定的概念。
此处的@property到底有没有扩充成员变量
我个人想到的简单的方法就是
赋值一下,系统就报错了,没定义该变量~
结果:
分类中不能添加成员变量
(大神们,本文很多自己理解,如果有错请指出,初学者“班门弄斧”了)
补充:(@dynamic,动态绑定)
@dynamic告诉编译器,属性的setter与getter方法由用户自己实现,不自动生成。(当然对于readonly的属性只需提供getter即可)。假如一个属性被声明为@dynamic var,然后你没有提供@setter方法和@getter方法,编译的时候没问题,但是当程序运行到instance.var =someVar,由于缺setter方法会导致程序崩溃;或者当运行到 someVar = var时,由于缺getter方法同样会导致崩溃。编译时没问题,运行时才执行相应的方法,这就是所谓的动态绑定。
对于这个警告的消除:
在另一篇文章中还提到了另外的方法:
http://www.cnblogs.com/starer/p/3813674.html