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 修饰 还是不够安全 .

你可能感兴趣的:(iOS开发基础:property修饰词)