Objective-C中的@property

作者: sellse | 来源:发表于2015-09-07 14:39 被阅读323次
    Objective-C中的@property
    按照先来后到的顺序,在了解@property之前,必须先了解accessor(存取器)的概念,这对于理解@property有很大帮助。

    1.什么是存取器

    accessor(存取器):顾名思义,指用于获取和设置对象实例变量的方法。《Cocoa Design Patterns》把它归类为基础模式中的一种。用于获取实例变量值的存取器是getter,用于设置实例变量值的存取器是setter
    在Cocoa中accessor(存取器)有很多优点:

    • 灵活性与方便维护:可在accessor(存取器)中改变并实现不同的实例变量访问方式而不影响其他代码,方便对实例变量的更改维护。
    • 内存管理:accessor(存取器)方法提供了简单的方法把内存管理代码隔离在少部分代码中。
    • 支持KVC和KVO:KVC和KVO是很强大的技术。但是它们依赖于正确命名accessor(存取器)

    2.那么怎么创建存取器呢

    先上代码:

    // h文件
    import <Foundation/Foundation.h>
    
    @interface Person : NSObject
    {
    // 实例变量
    NSString *name;
     }
    // setter                                   
    - (void)setName:(NSString *)newName; 
    // getter
    - (NSString *)name;
    @end  
    

    上面的代码中name就是Person的实例变量,并且可以看到对这个实例变量声明了get/set方法,即存取器

    //m文件
    #import "Person.h"
    @implementation Person
    // setter
    - (void)name:(NSString *)newName
    {
        name = newName;
    }
    // getter
    - (NSString *)name
    {
        return name;
    }
    // setter
    @end
    

    上面代码是对实例变量存取器的实现。我们可以看到,存取器就是对实例变量进行赋值和取值。按照约定赋值方法以set开头,取值方法以实例变量名命名。

    如果要为实例变量赋值或取值,可以这样操作:

    Person *person = [[Person alloc] init];
    //赋值
    [person setName:@"jack"];
    //取值
    [person name];
    

    3.那么终于该说说@property和@synthesize了

    accessor(存取器)是很重要的技术,在用不同的方式来获取或设置实例变量时,accessor(存取器)给了我们很大的灵活性,有时还涉及到内存管理。
    但是有没有更方便的方式去完成accessor(存取器)的工作呢,有——Objective-C 2.0加入了@property@synthesize,前者用于声明,后者用于合成accessor(存取器),结合使用就可以自动生成accessor(存取器)了,也就是说,这两个关键字可以省略刚刚出现的大段略显累赘的代码。
    不妨把刚才的代码翻译一下:

    // h文件
    #import <Foundation/Foundation.h>
    @interface Person : NSObject
    {
        // 实例变量
        NSString * name;
    }
    @property(nonatomic,strong) NSString * name;
    @end
    

    上面代码中使用@property声明了name属性,名称与实例变量名称相同。

    // m文件
    #import "Person.h"
    @implementation Person
    @synthesize name;
    @end
    

    如上,m文件中使用@synthesize自动生成这name实例变量的accessor(存取器),并且隐藏了它,使代码简洁了很多。
    既然使用了新的关键字,存取值时也会有些不同:

     Person *person = [[Person alloc] init];
    //存取值
     person.name = @"jack";
    

    对比之前的代码,Person对象使用点语法给存取器发送消息,区别于之前的方括号语法。并且getset的语法是相同的,所以这里的点语法可以根据语境自动判断我们是要赋值还是取值。当然,毕竟是对之前accessor(存取器)的简化,所以在这里方括号的语法也是可行的,操作时就跟之前的一样了。

    所以@ property@ synthesize的作用就很清晰了,@ property相当于声明实例变量的get/set方法,@synthesize相当于在m文件中实现实例变量的get/set方法。而代码要比accessor(存取器)简洁很多,存取时都可以使用点语法。

    也许你注意到了,本篇并没有提到@ property ()括号中的关键字,我将在下一遍文章中详细说明。

    相关文章

      网友评论

      • 546055050dc0:能否结合实例说一下,初学者还是比较疑惑
        sellse:@EXALEX 可以的,写完下篇可以写个小教程哈哈

      本文标题:Objective-C中的@property

      本文链接:https://www.haomeiwen.com/subject/mllycttx.html