zoukankan      html  css  js  c++  java
  • 04-@property增强(神器)

    1、@property 增强的介绍

      1> Xcode 4.4之后,@property 独揽了 @synthesize  的功能,也就是说@property可以同时生成sette和getter的声明和实现

      2>默认情况下,setter 和 getter的实现中,会去访问下划线_开头的成员变量

    例如:

     1 #import <Foundation/Foundation.h>
     2 @interface Dog : NSObject
     3 @property int age;
     4 @end
     5 
     6 @implementation Dog
     7 @end
     8 
     9 int main()
    10 {
    11    Dog *d = [Dog new];
    12    d.age = 5;
    13    NSLog(@"狗的年龄:%i岁", d.age);
    14 }

    分析:我们没有声明成员变量_age,也没有实现,但是却能正常运行程序。

    @property 增强后可以完成以下3件事:

    (1)声明成员变量

    (2)实现成员变量

    (3)创建一个成员变量

    第3行:@property int age;  就完成了上面所说的3件事,因此无需在@interface中声明和@implementation中实现_age变量,同时创建了一个成员变量_age。

    2、注意点

      由于没有在@interface中声明成员变量,在@implementation中会默认生成@private类型的成员变量

    即:在@implementation @end之间生成了一个_age变量,并且变量的作用域为@private(私有),只有在本类中可以直接访问,外界要访问,就得使用set get方法来间接访问。这也算是一个局限性。

    3、细节问题

    (1)@synthesize age = _age;

      1>setter getter实现中会访问成员变量_age;

      2>如果成员变量不存在,就会自动生成一个@private的成员变量_age

    (2)@synthesize age;  没有具体指定访问哪个成员变量。

      1>setter getter实现中为访问成员变量age

      2>如果成员变量不存在,就会自动生成一个@private的成员变量age

    代码如下:

     1  #import <Foundation/Foundation.h>
     2  @interface Dog : NSObject
     3  int _age;
     4   5  @property int age;
     6  @end
     7  
     8  @implementation Dog
     9  @synthesize age;
    10  @end
    11  
    12 int main()
    13 {
    14     Dog *d = [Dog new];
    15     d.age = 5;
    16     NSLog(@"%i", d.age);
    17 }

    第9行@synthesize age;没有具体说明要访问哪个成员变量,这时候它会优先访问跟它名称一样的成员变量,即age变量。发现没有age变量,就会在实现中自动生成一个@private的age变量。

    如图:说明访问的是age变量,而不是_age变量。

    (3)手动实现

      1>若手动实现了setter方法,编译器就只会自动生成getter方法

     1 #import <Foundation/Foundation.h>
     2 @interface Dog : NSObject
     3 @property int age;
     4 @end
     5 
     6 @implementation Dog
     7 - (void)setAge: (int)age;
     8 {
     9     _age = 10;
    10 }
    11 
    12 @end
    13 
    14 int main()
    15  {
    16     Dog *d = [Dog new];
    17     d.age = 5;
    18   NSLog(@"%i", d.age);
    19 }

    分析:

    a> 由于我们自己书写了setter的实现,编译器只会自动生成getter的实现和创建成员变量_age

    b> 运行程序:第17行 d.age 调用setter 给_age 赋值,这时由于setter方法的实现是我们手动书写的,编译器会默认尊重用户的选择,所有_age的值为10。

    如图:

    运行输出结果为10。如图:

      2>若手动实现了getter方法,编译器就只会自动生成setter方法

     1 #import <Foundation/Foundation.h>
     2 @interface Dog : NSObject
     3 @property int age;
     4 @end
     5 
     6 @implementation Dog
     7 - (int)age
     8 {
     9     return 10;
    10 }
    11 
    12 @end
    13 
    14 int main()
    15  {
    16     Dog *d = [Dog new];
    17     d.age = 5;
    18   NSLog(@"%i", d.age);
    19 }

    分析:

    1>在@implementation中,由于我们手动书写了getter的实现,编译器就不在自动生成getter的实现

    2>编译器只生成setter的实现和成员变量_age

    3>运行程序:第17行 d.age = 5;对_age进行了赋值, _age 的值变为5,如图

    但是到第18行, d.age 调用getter,这时去@implementation中寻找,找到我们自己书写的 getter 实现, 输出结果为:10 如图:

      3>若同时实现了setter和getter方法,编译器就不会自动生成不存在的成员变量

    分析:

    1>由于我们手动书写了setter 和  getter 的实现,编译器默认没有实现使用成员变量,就不在自动生成_age。

    2>由于缺少成员变量,于是出现报错

    一句话,一切以手动写的为优先。

    人生之路,不忘初心,勿忘始终!
  • 相关阅读:
    allocation size overflow
    数据库隔离级别深入理解(ORACLE)
    查看Orcale数据里的表是否有变化
    意外发现抽象类的构造器
    C语言学习快速笔记
    由javascript的闭包引申到程序语言编译上的自由变量作用域的考量
    easyui的datagrid的列checkbox自定义增加disabled选项
    数据库连接不关闭造成的问题以及RowSet的使用
    Quartz的JobDetail没有触发器指向时会被删除的问题
    发现浏览器开发工具的一个小问题
  • 原文地址:https://www.cnblogs.com/xdl745464047/p/4001594.html
Copyright © 2011-2022 走看看