A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

© Eil.tea 中级黑马   /  2015-8-6 22:16  /  833 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

问题:视频里讲@property的时候,说他相当于省略了函数声明里的setter和gettet,难道说还得写它们的实现吗?经过测试后,根本不需要实现,而且 @property 后边的类型和变量名可以是任意的,主函数都可以访问。举个例子。

  1. @interface Person : NSObject
  2. @property int a;
  3. @end
复制代码

不做get和set方法的实现
Person *p=[Person new];
直接输出p.a的时候,输出的是null,如果给p.a先赋值,再输出就可以是赋值的数,也就是说,即便是不去实现get和set方法,程序依然正确切完整。
那我是否可以理解成。
@property int a;这句代码做的工作是
1、声明部分的
  1. -(void)setA:(int)a; 和-(int)a;
复制代码

2、实现部分的
  1. -(void)setA:(int)a<span style="line-height: 2.2em;">{</span>
复制代码
3、成员变量定义部分
  1. @private int _a;
复制代码
4、如果在定义、声明、和实现的部分,将会替代系统自定义的部分,但是不会冲突。
关于第四点,我是这样测试的,首先验证如果定义了变量_a,那么这个访问器是否会改变_a的值。代码如下
  1. #import <Foundation/Foundation.h>
  2. @interface Person:NSObject
  3. {
  4.     @public
  5.     int _a;
  6. }
  7. @property int a;
  8. @end
  9. @implementation Person
  10. @end
  11. int main(int argc, const char * argv[]) {
  12.     @autoreleasepool {
  13.         Person *p=[Person new];
  14.         p.a=12;
  15.         NSLog(@"%d",p->_a);
  16.     }
  17.     return 0;
  18. }
复制代码
输出的结果是12,也就是视频里讲的@property代替了get和set方法,很明显上边的代码我是没有写方法的实现的,所以,方法的实现系统也已经自定义了。
有了上边的结果,那如果我自定义实现中的方法,是否有效呢?所以又写了如下代码
  1. #import <Foundation/Foundation.h>
  2. @interface Person:NSObject
  3. {
  4.     int _a;
  5. }
  6. @property int a;
  7. @end
  8. @implementation Person
  9. -(int)a
  10. {
  11.     NSLog(@"我是方法的实现中的get方法");
  12.     return _a;
  13. }
  14. @end
  15. int main(int argc, const char * argv[]) {
  16.     @autoreleasepool {
  17.         Person *p=[Person new];
  18.         p.a=12;
  19.         NSLog(@"%d",p.a);
  20.     }
  21.     return 0;
  22. }
复制代码
输出的结果:我是方法的实现中的get方法
12
也就是说,自定义的get方法的实现,重写了@property中系统定义的get方法的实现。
但是很遗憾系统报了个警告,警告内容如下
Writable atomic property 'a' cannot pair a synthesized setter with a user defined getter
大概意思是,这个方法的实现,找不到一个配对的set方法。或许实现部分get要和set同步,否则会有警告,但不影响代码。

最后,我们把Person类中的  int_a删除,把方法的实现部分清空,发现依然可以进行访问,是不是可以理解成@property给自定义了一个@private 的 int _a;之所以没写成是@protected,是因为,子类中无法访问_a这个成员变量。
由于个人资料有限,又对此部分只是有所疑问,故此把问题发到这里,希望老师和各位高手能够解答心中疑惑,不胜感激。




3 个回复

倒序浏览
  1. #import <Foundation/Foundation.h>
  2. @interface Person:NSObject
  3. {
  4. @private int _a;
  5. }
  6. @property int a;
  7. @end
  8. @implementation Person
  9. //@synthesize a;
  10. -(void)test
  11. {
  12.     NSLog(@"%d",_a);
  13. }
  14. @end
  15. int main(int argc, const char * argv[]) {
  16.     @autoreleasepool {
  17.         Person *p=[Person new];
  18.         p.a=12;
  19.         NSLog(@"%d",p.a);
  20.         [p test];
  21.     }
  22.     return 0;
  23. }
复制代码
后边老师又讲了@synthesize,有发生了一件神奇的事情,上边的代码,会输出两个12,也就是说:_a的值也改变了,可是如果把//@synthesize a;这行代码的注释去掉,_a又没有值了,@synthesize a; 又跟@property int a;配对了,真的很神奇有木有!!!
回复 使用道具 举报
看了后边的的内容才知道已经增强了。。。。囧rz
回复 使用道具 举报
请问有OC基础的完整视频吗,Q291876969
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马