跳到主要内容

以下 keywords 有什么区别: assign vs weak , __block vs __weak ?

参考答案:

assign, weak, __block, 和 __weak 都是在 Objective-C 和 Swift 中用于处理对象引用和变量捕获的关键词,但它们各自有不同的用途和语义。

  1. assign vs weak

    • assign: 通常用于非对象类型,如基本数据类型(int, float, enum 等)。当使用 assign 时,不会增加对象的引用计数。如果你尝试将一个对象赋值给一个 assign 修饰的属性,编译器会发出警告。
    • weak: 用于对象类型,但它不会增加对象的引用计数。这意味着当没有其他强引用指向该对象时,对象可以被释放。weak 主要用于避免循环引用,通常与代理(delegate)或回调块(callback blocks)一起使用。
  2. __block vs __weak

这两个关键词主要用于块(block)中,它们决定了块如何捕获其外部作用域的变量。

* **__block**: 允许块修改和保留其捕获的变量的值。当使用 `__block` 修饰一个变量时,块会创建该变量的一个副本(或引用),并在块执行期间保留这个副本。这意味着你可以在块内部修改这个变量的值,并且这个修改会反映到原始变量上。但是,请注意,对于对象类型,`__block` 不会增加对象的引用计数,因此如果原始对象在块外部被释放,块内部的引用可能会变为悬空指针。
* **__weak**: 当在块中使用 `__weak` 时,它创建了一个对原始变量的弱引用。这意味着块不会保留该变量的值,也不会增加其引用计数。如果原始变量在块执行之前被释放,那么块中的弱引用将自动变为 `nil`。这有助于避免在块中访问已被释放的内存(即悬空指针问题)。

总结

  • assignweak 主要用于属性声明,以指定对象如何被引用和管理。
  • __block__weak 主要用于块中,以指定块如何捕获其外部作用域的变量。

在选择使用哪个关键词时,你需要考虑你的具体需求,比如是否要修改变量的值、是否要避免循环引用或悬空指针问题等。