美文网首页
OC-属性简介

OC-属性简介

作者: 狸猫副园长 | 来源:发表于2016-11-02 20:17 被阅读321次

    OC中,任何属性都有3种特性,分别是

    1.多线程特性
    2.读/写特性
    3.内存管理特性

    多线程特性

    多线程特性有nonatomic和atomic两种,分别表示非原子性和原子性。默认使用atomic,提供线程安全保护。但我们一般设置为nonatomic。

    读写特性

    读写特性有readwrite和readonly两种,默认使用readwrite,使用readwrite编译器会生成存取方法,如果只使用readonly方法,则只会生成取方法。

    内存管理特性

    内存管理特性相对复杂,有strong、retain、weak、copy、unsafe_unretained、assign集中形式。

    OC对象属性可使用strong、retain、weak、copy,默认值为strong
    其中strong与retain等价,表示强引用,正常情况下使用这个特性;
    weak表示弱引用,当两个对象是父子关系,且子对象持有对父对象的引用时,该引用需要声明为weak,否则会导致引用循环;
    copy表示返回对象的副本,拥有可变子类的对象需要用该特性声明,如NSArray,NSDictionary,NSData,NSString,但它们的可变子类仍使用strong

    非对象属性可使用unsafe_unretained、assign
    ,默认值为unsafe_unretained,两者等价

    参考

    被无数人写过的assign,retain,strong,weak,unsafe_unretained,还有copy
    iOS中代理属性为什么要用Weak修饰?

    常见问题

    什么情况使用 weak 关键字?相比 assign 有什么不同?

    1.在ARC中,有可能出现引用循环的,使用weak。如delegate作为属性时,需要声明为weak。
    2.自身已经进行了强引用,没必要再使用强引用,不过使用强引用也没有问题,如使用storyboard创建的viewController,那么会有一个叫 _topLevelObjectsToKeepAliveFromStoryboard的私有数组强引用所有top level的对象,同时top level对象强引用所有子对象,那么vc没必要再强引用top level对象的子对象。

    不同点:
    1.使用范围:一般assign用于简单数据类型,在非ARC时代,它是属性的默认值,在ARC时代,一般使用unsafe_unretained,而weak则必须用于OC对象。
    2.对象释放的表现:当weak指向的对象被释放时,属性值会置空,而assign则不会,这时使用该属性访问对象可能会导致程序崩溃。

    怎么用 copy 关键字?(什么时候使用Copy)

    1.NSString、NSArray、NSDictionary,NSData 等等经常使用copy关键字,是因为他们有对应的可变类型:NSMutableString、NSMutableArray、NSMutableDictionary,NSMutableDate;他们之间可能进行赋值操作,为确保对象中的字符串值不会无意间变动,应该在设置新属性值时拷贝一份。

    2.block使用copy,block 使用 copy 是从 MRC 遗留下来的“传统”,在 MRC 中,方法内部的 block 是在栈区的,使用 copy 可以把它放到堆区.在 ARC 中写不写都行:对于 block 使用 copy 还是 strong 效果是一样的,但写上 copy 也无伤大雅,还能时刻提醒我们:编译器自动对 block 进行了 copy 操作。如果不写 copy ,该类的调用者有可能会忘记或者根本不知道“编译器会自动对 block 进行了 copy 操作”,他们有可能会在调用之前自行拷贝属性值。这种操作多余而低效。

    这个写法会出什么问题: @property (copy) NSMutableArray *array;

    两个问题
    1.使用copy,那么array的实际类型为NSArray,在调用NSMutableArray专有的方法,如[array removeObjectAtIndex:0];时程序会崩溃;
    2.没有指明多线程特性,默认使用的是atomic,影响性能。

    如何让自己的类用 copy 修饰符?如何重写带 copy 关键字的 setter?

    1. 若想令自己所写的对象具有拷贝功能,则需实现 NSCopying 协议。如果自定义的对象分为可变版本与不可变版本,那么就要同时实现 NSCopyingNSMutableCopying 协议。

    2. 如下

    - (void)setName:(NSString *)name {
        //[_name release];
        _name = [name copy];
    }
    

    @property 的本质是什么?ivar、getter、setter 是如何生成并添加到这个类中的

    1.@property = ivar + getter + setter
    2.自动合成,完成属性定义后,编译器会自动编写访问这些属性所需的方法,此过程叫做“自动合成”(autosynthesis)。需要强调的是,这个过程由编译器在编译期执行。默认为@synthesize firstName = _myFirstName;

    @property中有哪些属性关键字?/ @property 后面可以有哪些修饰符?

    任何属性都有3种特性,分别是

    1.多线程特性
    2.读/写特性
    3.内存管理特性

    1)多线程特性

    nonatomic和atomic,默认使用atomic,但我们一般设置为nonatomic。

    2)读写特性

    readwrite和readonly,默认使用readwrite,使用readwrite编译器会生成存取方法,如果只使用readonly方法,则只会生成取方法。

    3)内存管理特性

    strong、retain
    weak
    copy
    unsafe_unretained、assign

    OC对象属性可使用strong、retain、weak、copy,默认值为strong
    其中strong与retain等价,强引用,正常情况下使用这个
    weak表示弱引用,当出现父子关系而子又需要有指向父的指针时使用
    copy表示返回对象的副本,拥有可变子类时使用,如NSArray,NSDictionary,NSData,NSString,但它们的可变子类仍使用strong

    非对象属性可使用unsafe_unretained、assign
    ,默认值为unsafe_unretained,两者等价

    block使用copy修饰
    delegate使用weak修饰

    被无数人写过的assign,retain,strong,weak,unsafe_unretained,还有copy
    iOS中代理属性为什么要用Weak修饰?

    weak属性需要在dealloc中置nil么?

    不需要

    1.在ARC环境无论是强指针还是弱指针都无需在 dealloc 设置为 nil , ARC 会自动帮我们处理
    2.非arc中,weak属性指向的对象遭到摧毁时,属性值也会清空(nil out)。

    @synthesize和@dynamic分别有什么作用?

    @property有两个对应的词,一个是 @synthesize,一个是 @dynamic。如果 @synthesize和 @dynamic都没写,那么默认的就是@syntheszie var = _var;

    1. @synthesize 的语义是如果你没有手动实现 setter 方法和 getter 方法,那么编译器会自动为你加上这两个方法。
    2. @dynamic 告诉编译器:属性的 setter 与 getter 方法由用户自己实现,不自动生成。(当然对于 readonly 的属性只需提供 getter 即可)。假如一个属性被声明为 @dynamic var,然后你没有提供 @setter方法和 @getter 方法,编译的时候没问题,但是当程序运行到 instance.var = someVar,由于缺 setter 方法会导致程序崩溃;或者当运行到 someVar = var 时,由于缺 getter 方法同样会导致崩溃。编译时没问题,运行时才执行相应的方法,这就是所谓的动态绑定。

    ARC下,不显式指定任何属性关键字时,默认的关键字都有哪些?

    1. 对应基本数据类型默认关键字是

    atomic,readwrite,assign

    1. 对于普通的 Objective-C 对象

    atomic,readwrite,strong

    用@property声明的NSString(或NSArray,NSDictionary)经常使用copy关键字,为什么?如果改用strong关键字,可能造成什么问题?

    使用strong,如果给该属性赋值时,赋值的类型是可变类型,则外部的修改会影响到该属性的值,使用copy相当于建立一个备份,不会影响。

    @property (nonatomic ,readwrite, strong) NSArray *array;
    
      NSMutableArray *mutableArray = [[NSMutableArray alloc] init];
      NSArray *array = @[ @1, @2, @3, @4 ];
      self.array = mutableArray;
      [mutableArray removeAllObjects];;
      NSLog(@"%@",self.array);
    

    打印结果为空。

    @synthesize合成实例变量的规则是什么?假如property名为foo,存在一个名为_foo的实例变量,那么还会自动合成新变量么?

    1)合成规则如下:

    1. 如果指定了成员变量的名称,但该成员变量没有声明,会生成一个指定的名称的成员变量,如果已经声明,则该属性对应操作该成员变量
    2. 如果不指定成员变量的名称,则会生成一个与属性同名的成员变量。例如,@synthesize foo; 还会生成一个名称为foo的成员变量
    3. 不写@synthesize时,编译器默认生成 @synthesize foo = _foo;

    2)此情况等同于以下情况

    @property (copy,nonatomic) NSString foo;
    
    @synthesize foo = _foo;
    

    根据合成规则第一条,不会再生成新变量。

    相关文章

      网友评论

          本文标题:OC-属性简介

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