如何在Objective-C ARC中对兄弟对象(可以是父对象)使用“强”和“弱”?

如何在Objective-C ARC中对兄弟对象(可以是父对象)使用“强”和“弱”?,objective-c,automatic-ref-counting,relationship,siblings,retain-cycle,Objective C,Automatic Ref Counting,Relationship,Siblings,Retain Cycle,我有两个Objective-C对象,它们以某种方式相互关联。你可能认为这是一种双向关系。使用ARC,我理解父对象应该持有对其子对象的强引用,而子对象持有指向其父对象的弱引用。但是如果父对象可以是任意一个对象呢?或者如果对象是“兄弟” 假设我有一个Person类,我想实例化两个对象,它们的兄弟属性彼此指向对方 @执行人 @财产(强,非原子)人*兄弟; 人物角色=[新人物]; Person personB=[新人员]; personA.brother=personB; 兄弟=人格; 这不会导致一个

我有两个Objective-C对象,它们以某种方式相互关联。你可能认为这是一种双向关系。使用ARC,我理解父对象应该持有对其子对象的强引用,而子对象持有指向其父对象的弱引用。但是如果父对象可以是任意一个对象呢?或者如果对象是“兄弟”

假设我有一个Person类,我想实例化两个对象,它们的兄弟属性彼此指向对方

@执行人
@财产(强,非原子)人*兄弟;
人物角色=[新人物];
Person personB=[新人员];
personA.brother=personB;
兄弟=人格;
这不会导致一个保留周期吗

这是另一个场景:假设我有一个约会类和职员类

@实施预约
@财产(强、非原子)员工*员工;
@执行人员
@财产(强、非原子)NSArray*任命;
在查看员工时,我可能希望显示所有员工的约会。因此,我可能会像这样实例化我的所有对象

Staff*bob=[Staff new];
预约*apptA=[预约新];
预约*apptB=[预约新];
apptA.staff=bob;
apptB.staff=bob;
bob.appointments=[NSArray arrayWithObjects:apptA,apptB,nil];
既然所有的引用都很强,这不会导致一个保留周期吗

最后,考虑一下这个场景:假设我把任命的员工属性变弱了。
@实施预约
@财产(弱、非原子)职员*职员;
这可能会解决我的第二个问题(上面的场景),但是如果我正在创建一个新的约会,并且我想附加一个新的工作人员,然后将对象传递到其他地方进行处理,该怎么办

+(无效)构建约会{
预约*appt=[预约新];
职员*职员=[新职员];
appt.staff=员工;
[自助预约:appt];
}
+(无效)保存约会:(约会*)应用{
//在这里用appt做点什么。
//我还会有员工吗?
}
由于my staff属性on Appointment现在很弱,因此在运行垃圾收集时是否有可能将其设置为nil(因为没有对staff对象的强引用)

编辑:由于本地
staff
变量(来自
buildAppointment
)仍在堆栈上,因此
app.staff
对象仍将存在。但是,如果我有:

+(void)创建和保存约会{
约会*约会=[self-createAppointment];
[自救预约:预约];
}
+(预约*)预约{
预约*appt=[预约新];
职员*职员=[新职员];
appt.staff=员工;
返回应用程序;
}
+(无效)保存约会:(约会*)应用{
//在这里用appt做点什么。
//我还会有员工吗?
}
我的同事似乎利用了两种特性来处理这一问题,一种是强势,另一种是弱势:

@实施预约
@财产(强、非原子)员工*staffStrong;
@财产(弱、非原子)员工*staffWeak;
-(职员*)职员{
如果(斯塔夫斯特朗!=零){
返回斯塔夫斯特朗;
}
返回工作人员弱;
}
-(无效)塞斯塔夫斯特朗:(职员*)职员{
斯塔夫斯特朗=工作人员;
staffWeak=零;
}
-(无效)SetTaffweak:(工作人员*)工作人员{
斯塔夫斯特朗=零;
员工=员工;
}
然后,在设置staff属性时,他们会根据需要使用setTaffStrong或setTaffBlew。然而,这似乎非常棘手-肯定有一个更优雅的解决方案?您将如何构建类来处理上述场景


PS:我为这个冗长的问题道歉;我尽量解释清楚

关于强引用与弱引用的一个一般性说明:强引用表示所有权,而弱引用表示关联。当两个对象都不拥有另一个对象时,通常会有其他对象拥有它们,或者它们都有来自局部变量的强引用

[code>人员类]不会导致保留周期吗

是的,会的,因为一个
人拥有他的兄弟,但他不应该拥有:这应该是一个弱势财产。这应该是可以的,因为应该有另一个对象(所有人的列表、按姓名组织人的字典或类似的东西)拥有所有
Person
对象。只要
Person
对象在该Person集合中,它就不会被释放

由于所有的参考资料都很丰富,[
任命
员工
]会不会导致一个保留周期

没错,这就是将要发生的事情
NSArray
保留进入其中的对象,在保留循环中关闭循环。请注意,您不能让
NSArray
变弱来打破这个循环:需要
Staff
变弱,而不是
约会

最后,考虑这个场景:假设我改变<代码>约定> /代码>代码>工作人员>代码>属性>代码>弱小/代码>。这可能解决了我的第二个问题(上面的场景),但是如果我正在创建一个新的约会,并且我想附加一个工作人员,然后将对象传递到其他地方进行处理,该怎么办

这没有问题:stack变量
staff
有一个强引用,所以它不会被释放

由于约会时my
staff
属性现在很弱,因此在运行垃圾收集时是否有可能将其设置为nil(因为没有对staff对象的强引用)

ARC不是垃圾收集系统:保留和释放发生在特定的、确定的时间点。
staff
不会发布,因为
staff*staff=[staff new]很强
+ (Appointment *)createAppointment {
    Appointment *appt = [Appointment new];
    // Registry gives you a reference to an existing Staff.
    // Since the object remains registered, that's not the last strong reference.
    Staff *staff      = [staffRegistry reserveMember];

    appt.staff = staff;

    return appt;
}