【iOS】属性关键字

属性分为三大类:

  1. 读写性控制
  2. setter相关修饰符
  3. 原子性修饰符

自动合成存取

@property

  • @property其实是在编译阶段由编译器自动帮我们生成setter方法,getter方法的

@synthesize

  • 当我们在实现文件中不写@synthesize propertyName时,在Xcode 4.5之前的版本不会帮我们自动实现setter和getter方法,系统当然也不再会为我们生成对应的成员变量。但是在Xcode 4.5之后可以不用写@synthesize
  • 当我们既定义了@synthesize,又在实现文件中人为重写setter和getter方法时,那么@synthesize将不再工作,也就不会为我们创建没有定义的_propertyName成员变量了,这时候如果在setter和getter方法中调用_propertyName将会发生编译错误

@dynamic

  • @dynamic 告诉编译器:属性的 setter 与 getter 方法由用户自己实现,不自动生成。

一.读写性控制

  • readOnly只读,只会生成getter方法,不会生成setter方法(但外部还是可以用KVC去赋值)
  • readWrite可读可写,会生成setter方法,也会生成getter方法(默认设置)

二.setter相关修饰符

  • assign:表示直接赋值,用于基本数据类型,包括id类型,这个修饰符不会牵涉到内存管理,但是如果是对象类型,使用此修饰符则可能会导致内存泄露。(不会使引用计数+1,也就是直接赋值)
  • retain:针对对象类型进行内存管理,如果对基本数据类型使用,则X-code会直接报错,当给对象类型使用此修饰符时,setter方法会先将旧的对象属性release掉,在对新的对象进行一次赋值并进行一次retain操作 (会使引用计数+1)
  • week:打开ARC时才会使用,相当于assign,可以把对应的指针变量置为nil
  • strong:打开ARC时才会使用,相当于retain
  • copy:建立一个索引计数为1的对象,在赋值时使用传入值的一份拷贝

copy

  • NSStringNSArrayNSDictionary 等等经常使用copy关键字,是因为他们有对应的可变类型:NSMutableStringNSMutableArrayNSMutableDictionary.为确保对象中的属性值不会无意间变动,应该在设置新属性值时拷贝一份保护其封装性block,也经常使用copy,关键字block。

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

  • 因为父类指针可以指向子类对象,使用copy的目的是为了让本对象的属性不受外界影响,使用copy无论给我传入是一个可变对象还是不可对象,我本身持有的就是一个不可变的副本.如果我们使用是strong,那么这个属性就有可能指向一个可变对象,如果这个可变对象在外部被修改了,那么会影响该属性.

深浅拷贝

关键字注释
浅复制(shallow copy)在浅复制操作时,对于被复制对象的每一层都是指针复制。
深复制(one-level-deep copy)在深复制操作时,对于被复制对象,至少有一层是深复制。
完全复制(real-deep copy)在完全复制操作时,对于被复制对象的每一层都是对象复制。

非集合类对象的 copy 与 mutableCopy

[不可变对象 copy] // 浅复制 
[不可变对象 mutableCopy] //深复制
[可变对象 copy] //深复制 
[可变对象 mutableCopy] //深复制

例如:

        NSArray* arr1 = [NSArray arrayWithObjects:@"苹果", @"桃子", @"葡萄", nil];
        NSArray* arr3 = [arr1 mutableCopy];
        NSLog(@"arr1 = %p, arr2 = %p, arr3 = %p", arr1, arr2, arr3);     //每个元素的指针地址相同

请添加图片描述

  • 如上,arr1和arr2地址相同,但与arr3不相同。
  • 因为arr1是不可变对象,arr2复制时使用copy关键字,进行了浅拷贝
  • arr3复制时使用mutableCopy关键字,创建了一个新的对象,进行了深拷贝

copy与strong关键字的差异

当我分别使用copy和strong关键字定义属性再进行复制时

@property (nonatomic, copy) NSArray* arr1;
@property (nonatomic, strong) NSArray* strongArr1;
NSMutableArray* test = [NSMutableArray arrayWithObjects:@"a", @"b", @"c", nil];
    self.arr1 = test;
    self.strongArr1 = test;
    
    NSLog(@"%p , %p",test, _arr1);
    NSLog(@"%p , %p",test, _strongArr1);
  • 可以看到,当我对test数组分别对copy和strong关键字定义的数组进行赋值时,用copy关键字声明的arr1属性的地址发生了变化,也就是产生了一个新的对象,进行了深复制。而用strong关键字声明的strongArr1属性的地址和test相同,进行了浅复制
  • strong修饰下,我们的strongArr1会持有原来的对象,使原来的对象引用计数+1,属于浅拷贝,这时候进行操作时,test和strongArr1的值都会发生改变
  • 一般来说对于不可变对象我们使用copy修饰从而防止它的值发送改变,而可变的对象使用strong修饰。

三.原子性修饰符

atomic:表示是线程安全的

nonatomic:表示是非线程安全的,使用此属性性能会提高一些

(系统默认是atomic)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值