iOS基础扩展[0005]iOS基础知识iOS知识

iOS开发中@property后面可以跟哪些修饰符以及我对ARC

2016-05-29  本文已影响1529人  Juice007

2016.5.30更新:

经评论区提醒:
其实还有两个特性:为空性nullability和自定义gettersetter方法名属性。
这两个特性比较简单也不太常用,所以就不纳入文章。

2016.6.3更新:

今天在《iOS编程》书中看到,block对象的属性声明应该为copy(本文之前的观点是weak)更为准确。因为Block对象是在栈中创建的,而其他对象是在堆中创建的。这意味着,即使应用针对新创建的Block对象保留了强引用类型的指针,一旦创建该对象的方法返回,那么与方法内部的其他局部变量相同,新创建的Block对象也会被立即释放。为了在声明Block对象的方法返回后仍然保留该对象,必须向其发送copy消息。拷贝某个Block对象时,应用会在堆中创建该对象的备份。这样,即使应用释放了当前方法的栈,堆中的Block对象也不会被释放。

2016.6.3更新:

本文之前指出IBOutlet属性应该设为weak,但是在WWDC2015上Apple官方推荐IBOutlet属性应该设为strong,除非需要避免引用循环的属性才设置为weak。在stackoverflow上有关于这个问题的讨论,我觉得最佳实践应该是顶层视图的IBOutlet属性使用strong,子视图的使用weak。(《iOS编程》中也是这个观点)
详见:http://stackoverflow.com/questions/7678469/should-iboutlets-be-strong-or-weak-under-arc


最近在找实习工作,几乎每次面试都会被问及@property后的三个关键字。网上不是说面试一个人的iOS开发水平,问个property就大概知道了。所以今天花了一些时间总结了一下,这些内容都来自于我看过的书以及在网上查阅的一些资料。

在iOS开发中,任何一个属性都有三个特性(@property后面可以跟三个关键字),每个特性都有多种不同的可选类型。

多线程特性

默认:atomic

总结:涉及到多线程的时候,使用atomic,保证安全。不涉及多线程,使用nonatomic,效率更高。

原子操作:是指不会被线程调度机制打断的操作。原子操作一旦开始,就要一直运行到结束,不会被打断。

读写特性

默认:readwrite

readonly一般用于设置内部数据的访问权限:某个对象中有一种可修改的数据,但是除该对象外,其他数据只能访问该数据而不能修改它。这时我们就可以为该数据另外设置一个readonly属性仅供外界读取,修改则在该对象中修改readwrite属性的数据。(这也是一种常用的设计模式)

内存管理特性(我对ARC的理解)

默认:strong
iOS5后使用ARC来管理内存。ARC的原则:只要某个对象被任一strong指针指向,那么他将不会被销毁。当对象没有被任何strong指针指向,那么该对象将被销毁。

@property (nonatomic, copy) NSString *string_1;
@property (nonatomic, strong) NSMutableString *string_2;
self.string_2 = [[NSMutableString alloc] init];
self.string_1 = self.string_2;

上述代码中string_2可能会被改变,但是string_1是不可变类型的。】
扩展:这个写法会出什么问题:

@property (nonatomic,copy) NSMutableArray *array;
```
添加,删除,修改数组内的元素的时候,程序会因为找不到对应的方法(`unrecognised selector`)而崩溃.因为 `copy` 就是复制一个不可变 `NSArray `的对象。

- `unsafe_unretained`:(不安全不引用)用于非对象属性(即:基本数据类型),这类属性不需要做内存管理,它表示存取方法会直接为实例变量赋值。【MRC时期使用`assign`】
【unsafe是相对于`weak`而言的。`unsafed_unretained`类型的指针指向的对象被销毁时,指针不会自动设置为`nil`,而是成为空指针,因此不安全。但是当处理非对象属性时是不会出现空指针问题的】
【unretained是指不会引起引用计数加1】

## 补充:
MRC时期的关键字:
- `assign`(赋值):表示简单的直接赋值操作。
 - 用于基本数据类型(`NSInteger`,`CGFloat`等)和C数据类型(`int`,`float`,`double`等)
 -  用于id类型。(比如delegate属性,使用`weak`可以避免出现强引用循环)【当id类型使用`assign`时,对象被销毁,指针不会被置空,可能会引起空指针】
【引入ARC后,`assign`的第一个功能已经被`unsafed_unretained`取代,第二个功能被`weak`取代】
- `retain`(持有):先`release`原来的值,再`retain`新值(引用计数会自动加1)。
```
-(void)setA:(ClassA *)a{
    if(_a!=a){
        [_a release];
        _a=[a retain];
    }
}
```
【引入ARC后,使用`strong`代替`retain`】

当然以上只是我目前的理解,我相信以后肯定会有更深的理解。所以我会随时更新我的新看法的。
上一篇下一篇

猜你喜欢

热点阅读