• Objective-C @property


    Objective-C @property
    ===
    
    我相信对于ios开发者来说,Objective-C的@property都是不太陌生的一个概念。不过最近我参加了一次面试,在问到相关问题的时候还是感觉如鲠在喉,可见一个简单的概念想要清晰的去解释还是需要深刻的理解。故而写这篇博客来巩固一下对于OC的@property的理解。
    
    ---
    ##@property是什么
    @property是编译器的指令
    
    什么是编译器的指令,编译器指令就是用来告诉编译器要做什么
    
    @property 告诉编译器声明属性的访问器(getter/setter)方法
    
    和@property配对使用的还有@synthesize指令
    
    @synthesize指令:告诉编译器,生成或合成属性的访问器(getter/setter)方法
    
    举例,原本我们需要写如下代码
    ```
    @interface PropertyTest : NSObject    
    {        
        NSString *name;    
    }    
    - (NSString *)name;    
    - (void)setName:(NSString *)newName;    
    @end
    ```
    使用@property和指令后
    ```
    @interface PropertyTest : NSObject    
    {
        NSString *name;
    }    
    @property (nonatomic, strong) name; 
    @end
    ```
    看上去不错,简洁漂亮。
    
    如果属性很多,@property能省下的代码量将会相当可观。
    
    ##@property的attribute
    细心点的就会发现,每个@property括号后面都跟了一个括号,括号里面是什么东西呢?括号里面呢是@property的attribute,可以理解为@property的设置。
    
    括号里面设置(attribute)不同,property所生成的setter方法也就不同。
    
    有哪些设置呢?我简单列举一下:
    
       * 
    atomic(默认):atomic意为操作是原子的,意味着只有一个线程访问实例变量。
       * 
    nonatomic: nonatomic跟atomic刚好相反。表示非原子的,可以被多个线程访问。
       * 
    readwrite(默认):readwrite是默认的,表示同时拥有setter和getter。
       * 
    readonly: readonly 表示只有getter没有setter。
       * 
    retain:释放旧值,retain新值
       * 
    assign(默认):用于值类型,如int、float、double和NSInteger,CGFloat等表示单纯的复制。还包括不存在所有权关系的对象,比如常见的delegate。
       * 
    strong:是在ARC伴随IOS引入的时候引入的关键字是retain的一个可选的替代。表示实例变量对传入的参数要有所有权关系即强引用。strong跟retain的意思相同并产生相同的代码,但是语意上更好更能体现对象的关系。
       * 
    weak: weak跟assign的效果相似,不同的是weak在对象被回收之后自动设置为nil。而且weak智能用在iOS 5或以后的版本,对于之前的版本,使用unsafe_unretained。
       * 
    copy:copy是为是实例变量保留一个自己的副本。
    
    atomic/nonatomic readwrite/readonly的功能都相对来说好理解
    
    剩下的attribute跟内存管理有点关系,下面我们讲点内存管理和@property的关系
    
    
    ---
    ##property和内存管理
    内存管理听上去很高大上有木有,内存管理博大精深,不过内存管理是一个笼统的概念,并不是一个很专业的技术概念。在Objective-C里我们主要通过引用计数来达到内存管理的目的。
    
    好吧,又来了一个概念叫引用计数。跟标题不符合啊!标题党啊!不要急,不要急,其实引用计数和内存管理是密不可分的。举一个二一点的例子。内存管理就是吃饱饭,那怎么样能吃饱饭呢?你吃米饭能吃饱,你吃面条也能吃饱。在OC里内存管理就是通过引用计数来完成,而在java里内存管理就是通过垃圾回收机制来完成。 所以接下来我们来讲讲引用计数。 
    
    >引用计数 
    >
    >这是一种古老但有效的内存管理方式。每个对象(特指:类的实例)内部都有一个retainCount的引用计数,对象刚被创建时,retainCount为1,可以手动调用retain方法使retainCount+1,同样也可以手动调用release方法使retainCount-1,调用release方法时,如果retainCount值减到0,系统将自动调用对象的dealloc方法(类似于c#中的dispose方法),开发人员可以在dealloc中释放或清理资源。
    
    
    上面一段话呢是从参考资料里复制出来的,简单的来说呢,当你创建一个对象的时候,对象里面就有了一个计数retainCount,初始值为1。当你对对象做一些操作的时候可以对这个retainCount的值做一些改变。那哪些操作可以更改这个计数呢? 简单列举一下:
    
       * 
    retain 计数加1。
       * 
    release计数减1
       * 
    autorelease 计数减1,但是不是立即执行,而是以推迟的方式。
    
    通过这些操作呢,我们对retainCount计数做出了修改,如果计数变为0的时候就会自动调用dealloc方法来释放对象和内存。
    
    屁话讲了一堆,那property和内存管理有毛关系,或者说property和引用计数有毛关系。 好吧,开始进入正题了.
    
    还记得上一节说的那个property的设置(attribute)吗 
    
    某些attribute会生成不同的set方法。那些不同的set方法里就有跟内存管理相关的内容。 让我们来看看哪些设置是根内存管理有关系的,让我来一一列举出来。
    
    **设置了assgin之后的setter方法**
    ```
    - (void)setName:(NSString *)newName 
    { 
        name = newName;
    }
    ```
    **设置了retain之后的setter方法** 
    ```
    - (void)setName:(NSString *)newName 
    { 
        if (newName != name) { 
            [name release]; // release旧值 
            name = [newName retain] //retain新值 
        } 
    }
    ```
    **设置了copy之后的setter方法**
    ```
    - (void)setName:(NSString *)newName 
    { 
        if (newName != name) { 
            [name release]; // release旧值 
            name = [newName copy] //copy新值 
        } 
    }
    ```
    
    跟内存相关的呢主要是这三个attribute
    
    还有两个attribute也要提及一下,就是 weak 和 strong
    
    retain 和 strong 功能基本一致
    
    weak能在对象自动销毁的时候自动赋值nil,主要用于解决循环应用的问题
    
    property如果拥有以上设置,成员变量的get方法里就会有相应的retain和release操作。这就是为什么说property跟内存管理有关系了。
    
    ##PS
    以上就是我对@property的简单理解,随着IOS开发的经验增加,对OC有更深入的理解后,我会继续补充。文章中可能有稍许纰漏,如果有疑问,烦请提出来一起讨论!
    
    
    **参考资料**:
    
    http://www.cnblogs.com/andyque/archive/2011/08/03/2125728.html
    http://www.cnblogs.com/yjmyzz/archive/2011/02/23/1958961.html
    
    
  • 相关阅读:
    mysql----show slave status G 说明
    mysqldump 的方式来搭建master-->slave 的复制架构
    C++----练习--string 从文件中一个一个单词的读直到文件尾
    python 全排列combinations和permutations函数
    什么是restful api
    git知识点
    Hash算法解决冲突的方法
    python之单例设计模式
    Linux常用命令大全
    SQLAlchemy中时间格式化及将时间戳转成对应时间的方法-mysql
  • 原文地址:https://www.cnblogs.com/peterpan507/p/3512598.html
Copyright © 2020-2023  润新知