Objective-C 中的弱属性和强属性设置器属性

Posted

技术标签:

【中文标题】Objective-C 中的弱属性和强属性设置器属性【英文标题】:Weak and strong property setter attributes in Objective-C 【发布时间】:2011-12-16 06:53:58 【问题描述】:

Objective-C 中的弱属性设置器属性和强属性设置器属性有什么区别?

@property(retain, [weak/strong]) __attribute__((NSObject)) CFDictionaryRef myDictionary;

有什么影响和好处?

听说weak在ios 4上不可用,我们需要使用assign。

weak类似于assign吗?

【问题讨论】:

***.com/questions/7306601/… 【参考方案1】:

您可以为特定文件打开或关闭 ARC。如果它打开了,则不能使用 retain release autorelease 等...而是使用 strong weak 属性或 __strong __weak 变量(默认为 __strong)。强相当于保留,但是 ARC 会为您管理发布。

你唯一想使用weak的时候,是你想避免保留循环(例如,父母保留孩子,孩子保留父母,所以两者都不会被释放)。

“免费桥接”部分(从NS 转换为CF)有点棘手。您仍然需要手动管理 CF 对象的 CFRelease()CFRetain()。当你将它们转换回 NS 对象时,你必须告诉编译器保留计数,以便它知道你做了什么。

都是here。

【讨论】:

【参考方案2】:

引用 Robert 引用的文档中明确回答您最后两个问题的部分:

// The following declaration is similar to "@property(assign) MyClass *myObject;"
// except that if the MyClass instance is deallocated,
// the property value is set to nil instead of remaining as a dangling pointer.
@property(weak) MyClass *myObject;

这称为归零弱引用。您可以使用 __unsafe_unretained 创建不将弱引用归零的弱引用,但顾名思义,通常不建议这样做。

也在文档中:

Weak references are not supported in Mac OS X v10.6 and iOS 4.

【讨论】:

是的,这是正确的,__unsafe_unretainedassign 的 ARC 版本。【参考方案3】:

这是我对变量属性的了解

    原子//默认 非原子 strong=retain //默认 弱 保留 赋值 //默认 unsafe_unretained 复制 只读 读写 //默认

所以下面是详细的文章链接,您可以在其中找到上述所有属性,这肯定会对您有所帮助。 非常感谢所有在这里给出最佳答案的人!

Variable property attributes or Modifiers in iOS

01.strong(iOS4 = 保留) - 它说“把它放在堆里,直到我不再指向它” - 换句话说“我是所有者,你不能在瞄准与保留相同的目标之前解除分配” - 只有在需要保留对象时才使用strong。 - 默认情况下,所有实例变量和局部变量都是强指针。 - 我们通常对 UIViewControllers(UI 项的父项)使用 strong - strong 与 ARC 一起使用,它基本上可以帮助您,不必担心对象的保留计数。完成后,ARC 会自动为您释放它。使用关键字 strong 意味着您拥有该对象。

例子:

@property (strong, nonatomic) ViewController *viewController;

@synthesize viewController;

02.弱(iOS4 = unsafe_unretained) - 它说“只要其他人强烈指出它,就保持这个” - 与分配相同,没有保留或释放 - “弱”参考是您不保留的参考。 - 我们通常对 IBOutlets(UIViewController 的 Childs)使用weak。这是因为只有子对象 只要父对象存在就需要存在。 - 弱引用是不保护被引用对象不被垃圾收集器收集的引用。 - 弱本质上是分配,一个未保留的属性。除了对象被释放时,弱指针自动设置为 nil

例子:

@property (weak, nonatomic) IBOutlet UIButton *myButton;

@synthesize myButton;

解释:Thanks to BJ Homer

想象我们的对象是一只狗,而狗想逃跑(被释放)。 强指针就像狗的皮带。只要你把皮带拴在狗身上,狗就不会逃跑。如果五个人将他们的皮带拴在一只狗身上(五个强指针指向一个物体),那么在所有五根皮带都脱离之前,狗不会逃跑。 另一方面,弱指针就像小孩子指着狗说“看!一条狗!”只要狗还在皮带上,小孩子仍然可以看到狗,他们仍然会指向它。然而,一旦所有的皮带都松开了,不管有多少小孩指着它,狗都会跑掉。 一旦最后一个强指针(leash)不再指向一个对象,这个对象就会被释放,所有的弱指针都会被清零。 当我们使用弱? 你唯一想使用弱的时候,是如果你想避免保留循环 (例如,父母保留孩子,孩子保留父母,因此两者都不会被释放)。

【讨论】:

在最初的列表中,我不太确定您所说的“默认”是什么意思。您将 strong=retainassign 都标记为默认值,但不能同时是两者。 喜欢狗的皮带比较。解释得很好。 很好的解释,虽然 iOS 不使用垃圾回收。 ARC != 垃圾收集(!),这些是不同的技术。 weak 和 unsafe_unretained 是不同的(第一个使用归零的弱引用,而后者是蹲) 我只是在学习 iOS,但似乎您在示例中放错了 weakstrong。父母有strong 对其子女的引用(作为UIViewController 类的myButton 属性,您已显示为weak)并且子女保留weak,这不是更有意义吗?对其父级的引用(例如您设置为 strong 的子类的 viewController 属性)。例如,阅读 Matt Neuburg 的 iOS 7 Programming Fundamentals 他表明,将其委托声明为属性的类将使其保持“弱”,这似乎很公平。【参考方案4】:

举个例子来详细说明(上面的答案已经很好了),希望这个例子能帮助更多

让我们有两个类 A 和 B

//A.h

#import <Foundation/Foundation.h>
#import "B.h"

@interface A : NSObject

@property (nonatomic, strong) B *objB;

@end

@implementation A
//

@end

//B.h

    #import <Foundation/Foundation.h>
    #import "A.h"


    @interface B : NSObject

    @property strong text(nonatomic, strong) A *objA;

    @end

    @implementation B
    //

    @end

    and in main

    #import "B.h"
    #import "A.h"

    
    A *obja =[[A alloc]init];
    B *objb =[[B alloc]init];
    A.objB=objb;
    B.objA=obja;
   

上面的代码会产生一个保留循环,因为两者都是强类型 a-------->b--------->a

所以为了避免它,你必须使用其中一个的 week 属性,以便它每周引用 对象,而不是增加它的引用计数。

【讨论】:

【参考方案5】:

WEAK 属性的明确使用如下:

Any control whose properties we need to change(eg:text of a label) is declared weak and as below:

@property(nonatomic,weak) IBOutlet Type *name;
Eg: @property(nonatomic,weak) IBOutlet UILabel *myLabel;

【讨论】:

在我的属性上使用弱,我收到警告说:“弱接收器可能被不可预测地设置为 nil”。我看过其他一些帖子,为了防止这个警告,你必须创建一个本地强引用。如果这是真的,如果最后我必须创建一个强引用,那么让属性变弱有什么意义?

以上是关于Objective-C 中的弱属性和强属性设置器属性的主要内容,如果未能解决你的问题,请参考以下文章

Objective-C 中的弱键字典

协商缓存和强缓存的区别

Swift 协议中的弱属性只能是类或类绑定协议类型

在不使用自引用的情况下设置 Objective-C 类属性

Objective-C:(私有/公共属性)为外部类调用设置只读属性,为自调用设置只读属性

在 Objective-C 中,如何设置属性的属性,即设置为另一个类属性的类?