iOS开发基础:property修饰词

修饰词:assign、weak、strong、retain、copy、nonatomic、atomic、readonly、readwrite


assign(ARC、MRC)
  1. 修饰整型等基本数据类型,直接赋值的意思。
  2. 如果没有weak、strong、retain、copy修饰,默认使用assign。
  3. 对象也可以用assign修饰,只是引用计数不会+1(与strong的区别)
  4. 如果用来修饰对象属性,对象销毁后是不会指向nil的,就会产生野指针错误。(与weak的区别)

weak(ARC)(对象)

  1. 针对对象的修饰词,不能修饰基本数据类型(int float)
  2. weak修饰的引用计数不会+1,也是直接赋值
  3. 弱引用是为了打破循环引用而产生的。
  4. 指针指向的对象如果被销毁,指针会指向nil,不会产生野指针错误。

在block中,block在copy的时候,会对内部使用到的对象引用计数+1,,如果使用[self 方法名],那么就会有一个强指针指向self所在的class的内存地址,class的引用计数+1,这样导致class所在的内存地址无法被释放,造成内存泄露

assign和weak区别:weak比assign多了一个功能。就是当属性所指向的对象消失的时候(也就是内存引用计数为0)会自动赋值为nil,这样再向weak修饰的属性发送消息就不会导致野指针操作crash。
举个例子:

//
//  ViewController.m
//  weak与assgin的区别
//
//  Created by 王海玉 on 2017/10/14.
//  Copyright © 2017年 王海玉. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()

@property (nonatomic,weak) id      weakPoint;

@property (nonatomic,assign) id    assignPoint;

@property (nonatomic,strong) id    strongPoint;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.strongPoint = [NSDate date];
    NSLog(@"strong属性:%@",self.strongPoint);

    self.weakPoint = self.strongPoint;
    self.assignPoint = self.strongPoint;
    self.strongPoint = nil;

    NSLog(@"weak属性:%@",self.weakPoint);
    //    NSLog(@"assign属性:%@",self.assignPoint)
}

@end

当注释打开时,程序就有可能会崩溃。(需要多运行几次)


retain ( MRC )

  1. release 旧对象( 旧对象计数器 -1 ) , retain 新对象( 新对象计数器 +1 ) , 然后指向新对象 .
  2. 在set方法里面是这样的 :
if(_dog!=nil) { 
  [_dog release];  
}
_dog= [dog retain];

strong ( ARC )(对象)

  1. 直接赋值并且对象的引用计数器 +1 .
  2. 在 ARC 里替代了 retain 的作用 .
  3. 直接指向该指针

copy ( ARC/MRC )

  1. copy 在 MRC 时是这样做的 release 旧对象( 旧对象的引用计数器 -1 ) , copy 新对象( 新对象的引用计数器 +1 ) , 然后指向新对象 .(新对象是指最终指向的那个对象,不管深拷贝还是浅拷贝)
  2. copy 在 ARC 时是这么干的 copy 新对象( 新对象的引用计数器 +1 ) , 然后指向新对象 .
    copy和mutableCopy区别
    举例:
    NSString *test1 =@"123456";
   // NSArray *array1 =[NSArray arrayWithObjects:@"123",@"123",@"123",nil];
    NSString *test2 =[test1 copy];
    NSString *test3 =[test1 mutableCopy];
    NSMutableString *test4 =[test1 copy];
    NSMutableString *test5 =[test1 mutableCopy];
    //test1 = @"asda";
    NSLog(@"地址1 %d 地址2 %d",test1,test2);
    NSLog(@"地址1 %d 地址2 %d",test1,test3);
    NSLog(@"地址1 %d 地址2 %d",test1,test4);
    NSLog(@"地址1 %d 地址2 %d",test1,test5);
运行结果
    NSString *test1 =@"123456";
    NSArray *test2 =[array1 copy];
    NSArray *test3 =[array1 mutableCopy];
    NSMutableArray *test4 =[array1 copy];
    NSMutableArray *test5 =[array1 mutableCopy];
    NSLog(@"地址1 %d 地址2 %d",array1,test2);
    NSLog(@"地址1 %d 地址2 %d",array1,test3);
    NSLog(@"地址1 %d 地址2 %d",array1,test4);
    NSLog(@"地址1 %d 地址2 %d",array1,test5);
运行结果

那么看来对NSString 和 NSArray来讲 copy都是浅copy,NSMutableCopy则是深度copy;

那么如果被copy的对象是可变的呢?

NSString *test1 = [NSMutableString stringWithFormat:@"123"];
//将第一行代码改成如下;
运行结果

则可以产生一个一样的结论,copy对可变字符串是深拷贝,而NSMutableCopy则对所有都是深度copy。

strong copy mutableCopy 区别

image.png

nonatomic ( ARC/MRC )

  1. 不对set方法加同步锁 .
  2. 性能好
  3. 线程不安全

非多线程时用效率高。


atomic ( ARC/MRC )

1.原子属性就是对生成的 set 方法加互斥@synchronized(锁对象) .

 @synchronized(self) { _delegate = delegate;}

2.需要消耗系统资源 .
3.互斥锁是利用线程同步实现的 , 意在保证同一时间只有一个线程调用 set 方法 .
4.其实还有 get 方法 , 要是同时 set 和 get 一起调用还是会有问题的 . 所以即使用了 atomic 修饰 还是不够安全 .

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 很多人讲属性修饰词的时候,喜欢从字面或者定义的角度介绍它们间的区别。这篇文章,我们侧重从修饰词对setter方法的...
    小码僧阅读 8,723评论 1 18
  • 搜罗世间美味,感知幸福瞬间! 民以食为天!而我,俨然是一个名副其实的“吃货”! 现在有许多明星,喜欢给自己一个“吃...
    十八加一阅读 3,192评论 0 4
  • 情感空洞的时候,感觉自己是个单一的人。我一直以为,心里充满期待和美好的愿望,可以实现理想。可惜,缺乏行动,一切都是...
    芥末小胖阅读 2,790评论 0 0
  • 转眼便是十五个秋,孩子为我纯情而写,感念之,转记以悦己愉人! 豆文选记(1) .....................
    落筆轩阅读 3,021评论 0 2
  • 文档原则:文档足够清楚和准确 只需包括设计或者开发过程中可能混淆的功能定义,只需记录在创建这个产品时已经确定下来的...
    逝也阅读 2,607评论 0 0