• @property 和@synthesize


    在Objective-C中,类的属性默认是protected的,也就是说只有该类以及它的子类才能存取它,如果要给外部使用的话,则需要来帮它加个setter/getter。
    例如:
    getter setter方法
    需要注意的是,在 Objective C 中, get 有着特殊的含义,所以 getter 方法直接使用属性名,而不是使用 get 然后再加上属性名。
    假定在非ARC环境下,用户包含书籍属性,那么直接这么写的 setter 方法存在内存泄露的危险, 怎么才能很好的避免这个问题呢?
    Person类中:

    #import "Book.h"
    {
        Book *_book;
    }
    - (void)setBook:(Book *)book{
        _book = book;
    }
    - (Book *)book{
        return _book;
    }

    这样在人引用了book后, 如果book释放, 人没有释放,那么就会出现野指针错误(Book object 0x100102940 overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug),如:
    野指针
    因此,应该在setter方法中,对使用的对象进行引用计数加1操作,释放的时候,对其引用计数减1, 改为:
    setter
    这样才能保证内存的有效性.

    当然, 上面仅仅只是三个Book属性,如果有10个、20个其他类属性,是不是也需要写大量这样的代码呢?
    答案当然是不用了.
    Objective C 2.0 为提供了@property和@synthesize。它大大简化了我们创建数据成员读写函数的过程,更为关键的是它提供了一种更为简洁,易于理解的方式来访问数据成员。
    上面的类可以简化为:
    简化
    注意:
    @property(.h文件)声明一个属性,自动生成setter 和 getter方法
    @synthesize(.m文件)实现setter 和 getter方法(Xcode不用写,是因为在.h文件声明property,自动完成synthesize的功能)。

    当然这样写也是存在内存泄露的,拿 Book 举例:

    @property Book *book;

    生成的getter 和 setter代码为:

    - (void)setBook:(Book *)book{
        _book = book;
    }
    - (Book *)book{
        return _book;
    }

    上面我们已经提到这种写法的错误性. 那应该怎么更改呢? 其实property为我们提供了控制setter生成的操作(非ARC的retain, ARC的strong), 将book属性改为:

    @property (retain) Book *book;

    生成的setter方法变为:

    - (void)setBook:(Book *)book{
        //传进来的book和_book不一样的时候
        if (book != _book){
            //对旧书(当前正在用的书)做一次release操作
            [_book release];
            //对新书做一次retain操作
            _book = [book retain];
        }
    }

    这样就可以保证内存的有效性,避免内存泄露.

    最后,对property提供的关键字进行总结(不同种类的可以一起用,同种类的只能选一个)
    控制set方法的内存管理
    retain : release旧值,retain新值(用于OC对象)在setter方法中,需要对传入的对象进行引用计数加1的操作。简单来说,就是对传入的对象拥有所有权,只要对该对象拥有所有权,该对象就不会被释放。

    assign : 直接赋值,不做任何内存管理(默认,用于非OC对象类型,如int、float、double和NSInteger,CGFloat等表示单纯的复制。还包括不存在所有权关系的对象,比如常见的delegate)

    strong:strong 是在 IOS 引入 ARC 的时候引入的关键字,是 retain 的一个可选的替代。表示实例变量对传入的对象要有所有权关系,即强引用。strong 跟 retain 的意思相同并产生相同的代码,但是语意上更好更能体现对象的关系。

    weak:在setter方法中,需要对传入的对象不进行引用计数加1的操作。简单来说,就是对传入的对象没有所有权,当该对象引用计数为0时,即该对象被释放后,用weak声明的实例变量指向nil,即实例变量的值为0。
    注:weak关键字是IOS5引入的,IOS5之前是不能使用该关键字的。delegate 和 Outlet 一般用weak来声明

    copy : release旧值,copy新值(一般用于NSString *)与strong类似,但区别在于实例变量是对传入对象的副本拥有所有权,而非对象本身

    控制需不需生成set方法

    readwrite :同时生成set方法和get方法(默认)
    readonly :只会生成get方法

    多线程管理
    atomic :性能低(默认) atomic意为操作是原子的,意味着只有一个线程访问实例变量。atomic是线程安全的,至少在当前的存取器上是安全的。它是一个默认的特性,但是很少使用,因为比较影响效率,这跟ARM平台和内部锁机制有关。

    nonatomic:性能高 nonatomic 跟 atomic刚好相反。表示非原子的,可以被多个线程访问。它的效率比atomic快。但不能保证在多线程环境下的安全性,在单线程和明确只有一个线程访问的情况下广泛使用。

    控制set方法和get方法的名称
    setter : 设置set方法的名称,一定有个冒号:
    getter : 设置get方法的名称

    不积跬步,无以至千里;不积小流,无以成江海。
  • 相关阅读:
    JDK框架简析--java.lang包中的基础类库、基础数据类型
    Mahout 模糊kmeans
    使用heartbeat+monit实现主备双热备份系统
    Git版本号控制:Git分支处理
    JAVA线程
    Nginx的特性与核心类别及配置文件和模块详解
    nginx设置反向代理后端jenklins,页面上的js css文件无法加载
    运维的危险命令,用了必死(1)
    xtrabackup备份MySQL
    利用ansible-playbook从测试环境获取tomcat中java项目新版本发布到生产环境
  • 原文地址:https://www.cnblogs.com/xiaocai-ios/p/7779798.html
Copyright © 2020-2023  润新知