zoukankan      html  css  js  c++  java
  • @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方法的名称

    不积跬步,无以至千里;不积小流,无以成江海。
  • 相关阅读:
    httpcontext in asp.net unit test
    initialize or clean up your unittest within .net unit test
    Load a script file in sencha, supports both asynchronous and synchronous approaches
    classes system in sencha touch
    ASP.NET MVC got 405 error on HTTP DELETE request
    how to run demo city bars using sencha architect
    sencha touch mvc
    sencha touch json store
    sencha touch jsonp
    51Nod 1344:走格子(贪心)
  • 原文地址:https://www.cnblogs.com/xiaocai-ios/p/7779798.html
Copyright © 2011-2022 走看看