Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 在ARC中,子对象如何告诉父对象我已完成,请释放我(以避免内存泄漏)_Ios_Objective C_Memory Leaks_Automatic Ref Counting - Fatal编程技术网

Ios 在ARC中,子对象如何告诉父对象我已完成,请释放我(以避免内存泄漏)

Ios 在ARC中,子对象如何告诉父对象我已完成,请释放我(以避免内存泄漏),ios,objective-c,memory-leaks,automatic-ref-counting,Ios,Objective C,Memory Leaks,Automatic Ref Counting,我的父对象创建一个子对象来执行一些异步操作。它涉及一些用户交互,这也是我没有使用NSOperation的原因之一。只有子对象知道它什么时候完成了任务,那么它如何告诉它的父对象我已经完成了,请释放我以避免内存泄漏 目前,我想到了这个,父对象有一个回调方法叫做releaseChild,它就是child=nil;当子对象完成其任务时,它调用父对象的releaseChild,将其自身设置为nil。实际上,我在之后将调用包装在一个dispatch\u中,但思想是一样的,子对象调用其父对象以将自身设置为ni

我的父对象创建一个子对象来执行一些异步操作。它涉及一些用户交互,这也是我没有使用
NSOperation
的原因之一。只有子对象知道它什么时候完成了任务,那么它如何告诉它的父对象我已经完成了,请释放我以避免内存泄漏

目前,我想到了这个,父对象有一个回调方法叫做
releaseChild
,它就是
child=nil
;当子对象完成其任务时,它调用父对象的
releaseChild
,将其自身设置为nil。实际上,我在之后将调用包装在一个
dispatch\u中,但思想是一样的,子对象调用其父对象以将自身设置为nil

我想知道有没有更好的办法

-----更新-----


我知道编写我的孩子的“正常”方法是创建一个
UIViewController
对象,将其推送到
UINavigationController
。当它完成后,用户可以弹出它,
ARC
将释放它。这样,我就不需要担心内存泄漏(通常)。但我认为,在完成时释放子对象(只有它知道何时完成)的问题比编写
UIViewController
对象有一个边界应用程序。

两种可能的解决方案

1) 使用协议委托方法让孩子告诉家长它已经完成了(我假设这就是你们正在做的)

2) 您可以将变量传递到子级,子级在完成执行后设置该变量,父级可以定期检查其值并清除子级(不是一个大风扇,而是一种轮询方法),可以使用创建的后台任务完成,也可以添加到低优先级队列

3) 使用NSNotificationCenter向家长发送通知,并告诉他工作已完成。您可以添加userinfo来标识彼此之间的子项

4) 如果在工作完成后不需要执行任何特定的操作,只需使用dispatch\u async,并且不保留引用,它将完成其任务并最终关闭


我需要更多的细节来向您推荐任何具体的方法。如果可能,请粘贴代码:)

如果子对象执行异步操作,则很可能在操作完成时调用回调块(成功或失败)。很可能父对象创建了子对象,存储了一个引用,告诉子对象启动异步操作,并给它一个回调块。因此,回调将是设置对nil的引用的最佳位置

在问题中:

只有子对象知道它什么时候完成了任务,那么它如何告诉它的父对象我已经完成了,请释放我以避免内存泄漏

在随后的评论中:

问题是子对象不能将自身设置为nil

看起来您需要的是一个子对象,它控制自己的生命周期。这很容易做到;只要一个变量中存储了一个对对象的引用,该对象就会保持活动状态,该变量被赋予对该对象中存储的引用的强所有权,并且该属性是变量声明的默认属性。这个变量可以是全局的,局部的,实例的,这无关紧要。。。因此,要控制你自己的命运,一个对象只需要保持一个对自身的引用

下面的代码是复制自(我几年前写的一个答案,我可以从我自己那里抄袭;-)的,显示了一种方法:

@implementation MasterOfMyOwnDestiny
{
   MasterOfMyOwnDestiny *alsoMe;
}

- (void) lifeIsGood
{
    alsoMe = self;
}

- (void) woeIsMe
{
    alsoMe = nil;
}

...

@end
在您的情况下,您可以在初始化过程中将子项设置为
也设置为some
,这样子项就可以开始控制自己的生命周期。当孩子决定完成工作时,他只需调用
[self-woeIsMe]
作为最后的动作

注意:您当然可以删除这些方法,只需在子对象中直接设置实例变量,这使得任何其他对象都很难杀死子对象

如果父级出于任何原因需要对子级进行引用,而不是为了使子级保持活动状态,那么它可以将该引用存储在一个变量中,该变量属性为断言存储在其中的引用的弱所有权,例如:

__weak MasterOfMyOwnDestiny *myChild = [MasterOfMyOwnDestiny new];

这样的引用不会使
myChild
引用的对象保持活动状态,并且在该对象死亡时将自动设置为
nil

我可以知道什么类型的子类吗???只是一个带有UI和网络填充的“普通”cocoa对象,因此您需要覆盖
dealloc()
child
中的
方法,并使用
child
对象从
parent
调用该方法,然后做任何你想做的事情
释放
。伙计,你不明白我的问题。不要只是为了回答而回答是的,我已经正确地阅读了你的问题,在这里我不仅仅是为了回答,而是为了帮助开发人员,你是否尝试过上面提供的解决方案?如果不尝试,你怎么能说它不适合你的问题?+1表示1)&4),3)有效,但不适合,因为通知是未寻址的信息流(广播),但父对象是专用对象。2) …不,…真的,不。@Amin Negm Awad,问题是子对象不能将自身设置为零。它必须让其他人(例如它的父母)这样做。所以我不明白使用dispatch\u async如何做到这一点。除了答案,在某种程度上就是重复我说的话。我没有看到任何新的东西。我绝对不会使用2/3(不,也没有广播)解决方案1)(授权)让你通知家长,这样他就可以设置他的ivar。解决方案4)是正确的:在您的Q中,您说问题在于将对子对象的引用设置为
nil
。所以没有别的事可做了。在这种情况下,您根本不需要子引用。只需将其移除即可。块将子对象保持在闭合状态。当然,这是行不通的,如果你因为其他原因需要参考资料(取消?),可能是b