欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

@property 关键字的区别:assign 与 weak、__block 与 __weak、strong 与 copy

程序员文章站 2022-03-22 19:06:45
...

assign 与 weak 区别

assign 适用于基本数据类型,weak 适用于 NSObject 对象

Q: assign 其实可以修饰对象,那为什么不用来修饰对象呢?
被 assign 修饰的对象在释放后,指针的地址还是存在的,也就是说指针并没有被置为 nil,造成野指针。

Q: 为什么可以用 assign 修饰基本数据类型?
基本数据类型一般分配在栈上,栈中的内存是有系统自动管理的,不会造成野指针

weak 修饰的对象在释放后,指针地址会被置为 nil。

weak 使用场景

  • Block 中。ARC 下,有可能会出现循环引用的情况,为了避免循环引用,可以使用 weak 来解决。如 delegate 代理属性,常用 weak 关键字
  • IBOutlet 控件属性中。自身已经进行一次强引用,没有必要再强引用一次,所以可以使用 weak。

strong 与 copy 区别

  • strong 与 copy 都会使引用计数加 1,但 strong 两指针指向同一个内存地址,copy 会在内存里拷贝一份对象,两个指针指向不同的内存地址。

浅拷贝与深拷贝

浅拷贝后的内容与原始内容指针地址相同
深拷贝后的内容指向原始内容相关对象的一份拷贝,与原始内容指针地址不同(深拷贝会逐个元素发送 copy 消息,用拷贝得到的元素创建 set)

简而言之,浅拷贝为指针拷贝,深拷贝为内容拷贝

[immutableObject copy];  // 浅拷贝
[immutableObject mutableCopy];  // 深拷贝
[mutableObject copy];  // 深拷贝
[mutableObject mutableCopy];  //  深拷贝

__block 与 __weak 区别

__block 修饰的变量,在 block 代码块中可以被修改

__weak 修饰的变量不会在 block 块中被 retain

__weak typedof(self) weakSelf = self;

block 变量定义是为什么用 copy?block 放在哪里?

block 本身也是一个对象。block 在创建的时候,内存地址是分配在栈上的,可能被随时回收。
block 本身的作用域是属于创建时的作用域,在创建时候的作用域外调用 block 会导致程序崩溃。
copy 可以将 block 拷贝到堆中,保证 block 的声明域外可使用

栈 stack 和 堆 heap

stack
heap
.bss
.data
.text

栈区

LIFO,系统自动分配。
一般放函数参数值、局部变量的值等。编译器自动创建和释放。

堆区

可以自己申请内存创建大小,也需自己释放。

block 为什么不用 strong

如果 block 用到 self,就会 retain self,如果是 strong 修饰的话,会造成循环引用。