strong,weak,assign,copy 的区别与作用

iOS内存管理
内存管理是指软件运行时对计算机内存资源的分配和使用技术,其最重要的目的是如何高效、快速的分配,并且在适当的时候释放和回收内存资源。
iOS中数据是存在堆和栈中的,然而我们的内存管理管理的堆上的内存,栈上的内存并不是我们管理

  • 非OC对象(基础数据类型)存储在栈上
  • OC对象存储在堆上

strong:表示指向并拥有该对象,不会开辟新的内存空间属于浅拷贝。其修饰的对象引用计数会增加1。该对象只要引用计数不为0则不会被销毁。当然强行将其设为nil可以销毁它。

weak:表示指向但不拥有该对象。其修饰的对象本身引用计数不会增加。无需手动设置,该对象会自行内存中销毁。

assign:主要用于修饰基本数据类型,如NSInteger和CGFloat,这些数值主要存在于栈上。

copy
    1、源对象是不可变对象,不论是copy还是strong属性,所对应的值时不发生变化,strong和copy并没有开辟新的内存,并不是深拷贝。此时使用copy和strong,并没有对数据产生影响。
    2、数据源为可变对象时,使用copy申明属性,会开辟一块新的内存空间存放值,源数据不论发生怎么变化,都不会影响copy属性中的值,属于深拷贝。
    3、NSString用copy是深拷贝,会开辟一块新的内存。

weak和assign区别

1、修饰变量类型的区别

  • weak 只可以修饰对象。如果修饰基本数据类型,编译器会报错-“Property with ‘weak’ attribute must be of object type”。
  • assign可修饰对象和基本数据类型。当需要修饰对象类型时,MRC时代使用unsafe_unretained。当然unsafe_unretained也可能产生野指针,所以它的名字是unsafe_un

2、是否产生野指针的区别

  • weak不会产生野指针。因为weak修饰的对象释放后(引用计数值为0),指针会被系统置为nil,之后再向该对象发消息也不会崩溃。weak是安全的
  • assign如果修饰是对象,会产生野指针问题;如果修饰基本数据类型是安全的。修饰的对象释放后,指针不会自动置空,此时向对象发消息会崩溃。

3、assign和weak都可以修饰对象类型,但是assign修饰的对象存在内存问题

  • assign只适用于基本数据类型例如float,int,struct等值类型,不适用于引用类型。因为值类型会被放在栈区,遵循先进后出的原理,由系统负责管理栈内存。而引用类型会被放入堆中,需要我们手动管理内存或ARC管理
  • weak适用于delegate和block等引用类型,不会出现野指针,也不会循环引用

总结:weak一般用来修饰对象,assign一般用来修饰基本数据类型。原因是assign修饰的对象被释放后,指针的地址依然存在,造成野指针,在堆上容易崩溃。而栈上的内存系统会自动处理,不会造成野指针。

copy和strong区别:copy和strong类似,不同之处是strong的复制多个指针指向同一个地址,而copy的复制会在内存中拷贝一份对象,指针指向不同地址。copy一般用在修饰有可变对应类型的不可变对象上,如NSString,NSArray,NSDictionary。

NSArray和NSString声明类型用copy

  • 防止类型被修改
  • 防止值被修改

NSMutableArray、NSMutablestring、NSMutableDictionary声明类型用strong

  • 防止类型被修改,从而造成crash
  • copy声明的可变数据,初始化或复值之后,变成不可变对象,再对对象进行增,删会crash。这是因为copy属性修饰后,在初始化或赋值时会进行copy操作,然后赋值
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
我明白了,你要求将一个弱引用分配给一个变量。在 C++ ,可以通过使用 `std::weak_ptr` 来实现弱引用。`std::weak_ptr` 是一种智能指针,可以用于跟踪 `std::shared_ptr` 的生命周期。这样,当 `std::shared_ptr` 所管理的对象被销毁时,`std::weak_ptr` 会自动失效。下面是一个简单的示例代码: ```cpp #include <iostream> #include <memory> int main() { std::shared_ptr<int> sharedPtr = std::make_shared<int>(42); std::weak_ptr<int> weakPtr = sharedPtr; // 使用 weakPtr 获取对象的 if (auto lockedPtr = weakPtr.lock()) { std::cout << "Weak pointer value: " << *lockedPtr << std::endl; } else { std::cout << "Weak pointer expired" << std::endl; } // 销毁 sharedPtr sharedPtr.reset(); // 再次尝试使用 weakPtr 获取对象的 if (auto lockedPtr = weakPtr.lock()) { std::cout << "Weak pointer value: " << *lockedPtr << std::endl; } else { std::cout << "Weak pointer expired" << std::endl; } return 0; } ``` 在这个示例,`sharedPtr` 是一个 `std::shared_ptr`,并且我们使用它创建了一个 `std::weak_ptr`,即 `weakPtr`。我们可以通过调用 `lock()` 方法来检查 `weakPtr` 是否有效,如果有效,就可以使用它来获取所管理的对象的。当 `sharedPtr` 被 `reset()` 销毁后,再次使用 `weakPtr` 时,`lock()` 方法将返回一个空指针,表示弱引用已经失效。 希望这个示例能对你有所帮助!如果你有任何疑问,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值