• 点语法


    一、点语法的本质是方法的调用,而不是访问成员变量(OC中访问成员变量只能使用->),当使用点语法时编译器会自动展开成相应的方法(编译器特性)。

    点语法陷阱(ARC):

    1)死循环

    - (void)setAge:(int)age {
        self.age = age;
    }

    分析:self.age = age 实际为赋值调用 set 方法; 会被编译器展开成如下代码,造成了死循环!

    - (void)setAge:(int)age {
        [self setAge:age];
    }

    正确写法:

    - (void)setAge:(int)age {
        self->_age = age;
    }

    或:

    - (void)setAge:(int)age {
        _age = age;
    }

    说明:age为Person类的属性,在Person.m中我们可以使用 “->”访问私有成员变量 _age;

    2)死循环

    - (int)age {
        return self.age;
    }

    此处的 self.age 实际为取值,调用 get 方法,造成死循环。展开如下:

    - (int)age {
        return [self age];
    }

    分析:此处的self.age,是取值,则会被编译器转为 [self age];即调用了get方法,造成了死循环!

    正确写法:

    - (int)age {
        return self->_age;
    }

    或:

    - (int)age {
        return _age;
    }

    二、@property 和 @synthesize 关键字(编译器指令:告诉编译器要做什么)

    先说一说为什么使用 @property

    // .h
    @interface Person : NSObject {
        int _age;
    }
    
    - (void)setAge:(int)age;
    - (int)age;
    
    @end
    
    // .m
    @implementation Person
    
    - (void)setAge:(int)age {
        _age = age;
    }
    
    - (int)age {
        return _age;
    }
    
    @end

    以上是手动实现的 age 属性的 set/get 方法。

    @property 会告诉编译器,声明 age 属性的访问器(set/get)方法,免去我们手工书写的繁琐!

    示例:

    // .h 声明age属性
    @property (nonatomic, assign) int age; // 等同于声明了age属性set和get方法
    
    // 访问器
    - (void)setAge:(int)age;
    - (int)age;

    @synthesize 会告诉编译器,生成 age 属性(set/get)的实现!

    示例(通用写法):

    // 告诉编译器生成 age 属性的访问器,且在访问器里访问 _age 成员变量;如果没有 _age 成员变量,则自动生成@private的_age成员变量(私有的)
    @synthesize age = _age;
    // @synthesize 等同于set和get的实现,书写在@implementation……@end 之间
    - (void)setAge:(int)age {
        _age = age;
    }
    
    - (int)age {
        return _age;
    }

    示例:

    // .h
    @property (nonatomic, assign) int age;
    @synthesize age = _num;
    分析:表示用 age 的 setget 方法,修改 _num 属性变量的值
    
    - (void)setAge:(int)age {
        _num = age;
    }
    
    - (int)age {
        return _num;
    }

    示例:

    // 默认会访问 age 成员变量,而不是 _age;
    @synthesize age;

    三、Xcode4.4之后,

    1)@property增强版。只要:

    @property (nonatomic, assign) int age;

    好处:系统就会帮我们实现 age 属性的 set/get 方法。

    缺点:自动生成的成员变量 _age 是私有的,子类是不能访问的。

    如果让子类访问父类的 _age 成员变量,须手动实现 _age 成员变量:

    // .h 
    @interface Person : NSObject {
        int _age;
    }
    @property (nonatomic, assign) int age;
    @end
    // Man 继承自 Person
    @implementation Man
    - (void)test {
        // 父类Person,存在 _age 成员属性,则子类就可以使用 _age数形变量
        NSLog(@"%d", _age);
    }
    @end

    2)@property增强下重写 set/get 方法

    1)如果手动实现了set方法,那么编译器就只生成get方法和对应的成员变量;
    2)如果手动实现了get方法,那么编译器就只生成set方法和对应的成员变量;
    3)如果set和get方法都是手动实现的,那么编译器将不会生成成员变量,且报错(Use  of undeclared identifier ‘_age’)。

    若需要重写 set/get 方法,正确写法:

    @synthesize age = _age;
    
    - (void)setAge:(int)age {
        _age = age;
    }
    
    - (int)age {
        return _age;
    }

    尊重作者劳动成果,转载请注明: 【kingdev】

  • 相关阅读:
    linux下编译sphinx拓展
    Java为什么使用连接池
    内部类之.this&&.new
    何为代理
    Qt install Phonon
    Gcc简介与常用命令
    Vim的设置和使用——编程者
    QT程序启动界面的使用
    slide from one widget to another
    Hide the common top menu in Ubuntu 12.04
  • 原文地址:https://www.cnblogs.com/xiu619544553/p/4455776.html
Copyright © 2020-2023  润新知