iOS 关键词assign、strong、copy、weak、unsafe_unretained

关键词assign、strong、copy、weak、unsafe_unretained

影响:

  • 是否开辟新的内存
  • 是否有引用计数增加

strong

指向并拥有该对象。其修饰的对象引用计数会 +1,该对象只要引用计数不为 0 就不会销毁,置为 nil 可以销毁它。
一般用于修饰对象类型、字符串、集合类的可变版本NSMutable

// .h 文件
@property (nonatomic, strong) NSMutableArray * nArr;

// .m 文件
{
     NSMutableArray * mArr = [[NSMutableArray alloc]
                               initWithObjects:@"a", @"b", @"c", nil];

     self.nArr = mArr;   // setter方法赋值时,  指针拷贝(浅拷贝)

     [mArr addObject:@"d"];
     NSLog(@"%@  %p  %p", self.nArr, self.nArr, mArr);
}

//打印结果
2018-10-16 19:29:27.550029+0800 Demo[64192:936916] (
     a,
     b,
     c,
     d
)    0x60000005bc60     0x60000005bc60    // 地址相同

copy

调用该变量的setter进行赋值,会把对象(值)拷贝一份副本,再赋。两个指针指向不同的内存地址,持有两个不同的对象。另一个对象发生变化不影响本身。

一般NSString、NSArray、NSDictionary 等 用 copy 修饰,因为有可能赋值一个可变类型的指针,此时能保证属性值不会受外界影响。

// .h 文件
@property (nonatomic, copy) NSArray * nArr;

// .m 文件
{
     NSMutableArray * mArr = [[NSMutableArray alloc]
                              initWithObjects:@"a", @"b", @"c", nil];
     self.nArr = mArr;   // setter方法赋值时,  内容拷贝(深拷贝)

     [mArr addObject:@"d"];
     NSLog(@"%@  %p  %p", self.nArr, self.nArr, mArr);
}
2018-10-16 19:27:27.678093+0800 Demo[63966:933713] (
     a,
     b,
     c
)    0x60000024e070    0x60000024c960   // 地址不同

自定义对象需要实现NSCoping 协议:

- (instancetype)copyWithZone:(NSZone *)zone
{
     AModel * model = [[[self class] allocWithZone:zone] init];
     model.title = self.title;
     model.desc = self.desc;
     return model;
}

对比:strong 、copy
strong 的赋值是多个指针指向同一个地址,
copy 的赋值是每次会在内存中赋值一份对象,指针指向不同的地址。

  • 在MRC下,block属性为什么要用copy来修饰?
    因为block在创建时,它的内存是分配在栈(stack)上的,而不是在堆(heap)上,栈内存可能被随时回收。本身的作于域属于创建时的作用域,一旦在创建时候的作用域外调用block,将导致程序崩溃。通过copy可以把block拷贝到堆,保证block的声明域外使用。
    在ARC下写不写都行,编译器会自动对block进行copy操作。

assign

主要用于修饰 基本数据类型 等非OC对象,如 NSIntegerCGFloat等。
这些数值主要存在于中。

可以用来修饰对象。但是!被assign修饰的对象在释放后,指针的地址没被置为nil,成为野指针。如果后续在分配对象到堆上的某块内存时,正好分到这块地址,程序就会crash。

不管是 MRC 还是 ARC,使用 assign 时,都需要注意释放。

weak

指向 但不拥有该对象。其修饰的对象引用计数不会增加,属性所指的对象遭到摧毁时,值会清空。
ARC 环境下一般用于修饰可能会引起循环引用的对象。
delegate、xib 控件用 weak 修饰。

在使用 delegate 时,需要注意:

  • MRC 下,使用 assign。
  • ARC 下,都建议使用 weak,防止出现循环引用。否则如果用assign,当页面销毁时,很可能出现 delegate 对象无效,导致程序 crash。

unsafe_unretained

与 weak 类型相似,但是销毁时不自动清空,容易形成野指针。

对比:
weak 引用的 OC 对象被销毁时,指针会被自动清空,不再指向销毁的对象,不会产生野指针错误;
assign 修饰基本数据类型,内存在栈上由系统自动回收。修饰对象类型时,也可能存在野指针。



@property、@dynamic 和 @synthesize

@property

@property = ivr + getter + setter
编译器自动编写访问这些属性所需的方法。

@dynamic

告诉编译器不要自动创建实现属性所用的实例变量,也不要为其创建存取方法。即使编译器发现没有定义存取方法也不会报错,运行期会导致崩溃。

@synthesize

在类的实现文件里, 指定实例变量的名称。

源地址

原文地址:https://www.cnblogs.com/jiuyi/p/11551638.html

时间: 2024-11-06 07:33:10

iOS 关键词assign、strong、copy、weak、unsafe_unretained的相关文章

copy,assign,strong,retain,weak,readonly,nonatomic的区别

copy与retain:1.copy其实是建立了一个相同的对象,而retain不是:2.copy是内容拷贝,retain是指针拷贝:  3.copy是内容的拷贝 ,对于像NSString,的确是这样,但是如果copy的是一个NSArray呢?这时只是copy了指向array中相对应元素的指针.这便是所谓的"浅复制".4.copy的情况:NSString *newPt = [pt copy];此时会在堆上重新开辟一段内存存放@"abc" 比如0X1122 内容为@&q

[转载]IOS开发之----strong和weak (IOS5新特性)

iOS5中加入了新知识,就是ARC,其实我并不是很喜欢它,因为习惯了自己管理内存.但是学习还是很有必要的. 在iOS开发过程中,属性的定义往往与retain, assign, copy有关,我想大家都很熟悉了,在此我也不介绍,网上有很多相关文章. 现在我们看看iOS5中新的关键字strong, weak, unsafe_unretained. 可以与以前的关键字对应学习strong与retain类似,weak与unsafe_unretained功能差不多(有点区别,等下会介绍,这两个新关键字与a

iOS中assign、copy 、retain等关键字的含义

assign: 简单赋值,不更改索引计数copy: 建立一个索引计数为1的对象,然后释放旧对象 retain:释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1 Copy其实是建立了一个相同的对象,而retain不是:比如一个NSString对象,地址为0×1111,内容为@"STR" Copy到另外一个NSString之 后,地址为0×2222,内容相同,新的对象retain为1, 旧有对象没有变化 retain到另外一个NSString之 后,地址相同(建立一个指

iOS中assign,copy,retain之间的区别以及weak和strong的区别

@property (nonatomic, assign) NSString *title; 什么是assign,copy,retain之间的区别? assign: 简单赋值,不更改索引计数(Reference Counting). copy: 建立一个索引计数为1的对象,然后释放旧对象 retain:释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1 weak 和strong的区别: (weak和strong)不同的是 当一个对象不再有strong类型的指针指向它的时候 它会

iOS中assign,copy,retain之间的区别以及weak和strong的区别(面试)

• copy: 用于希望保持一份传入值的拷贝,而不是值自身的情况,即把原来的对象完整的赋值到另外一地方,重新加载一内存区,一个地方变了不影响另一个地方的对象. • assign:  简单的直接赋值,相当于说两个对象指向同个内存区,一个地方的变了,其他的也跟着改变. • retain:释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数 为1 那上面的是什么意思呢? Copy 其实是建立了一个相同的对象,而 retain 不是: 比如一个 NSString 对象,地址为 0×1111,

用property声明属性时,strong,copy,weak的一般用法

//一般情况下,在声明字符串对象的时候使用 copy //UI对象使用weak //其他对象使用strong @property(nonatomic,copy)NSString *name; @property(nonatomic,weak)UIImage *image; @property(nonatomic,strong)NSArray *array;

对于atomic nonatomic assign retain copy strong weak的简单理解

atomic和nonatomic用来决定编译器生成的getter和setter是否为原子操作 1)atomic 设置成员变量的@property属性时,atomic是默认值,提供多线程安全 在多线程环境下,原子操作是必要的,否则有可能引起错误的结果.加了atomic后setter函数会变成下面这样: {lock} if (property != newValue) { [property release]; property = [newValue retain]; } {unlock} 2)n

IOS开发 strong,weak,retain,assign,copy nomatic 等的区别与作用

strong,weak,retain,assign,copy nomatic 等的区别 copy与retain:1.copy其实是建立了一个相同的对象,而retain不是:2.copy是内容拷贝,retain是指针拷贝:  3.copy是内容的拷贝 ,对于像NSString,的确是这样,但是如果copy的是一个NSArray呢?这时只是copy了指向array中相对应元素的指针.这便是所谓的"浅复制".4.copy的情况:NSString *newPt = [pt copy];此时会在

IOS内存管理retain,assign,copy,strong,weak

IOS内存管理retain,assign,copy,strong,weak IOS的对象都继承于NSObject, 该对象有一个方法:retainCount ,内存引用计数. 引用计数在很多技术都用到: window下的COM组件,多线程的信号量,读写锁,思想都一样. (一般情况下: 后面会讨论例外情况)alloc 对象分配后引用计数为1retain 对象的引用计数+1copy copy 一个对象变成新的对象(新内存地址) 引用计数为1 原来对象计数不变 release 对象引用计数-1 如果为