Objective c 为什么没有保留指针需要使用release?
我有两个问题,但首先让我们从更容易混淆的问题开始Objective c 为什么没有保留指针需要使用release?,objective-c,ios,Objective C,Ios,我有两个问题,但首先让我们从更容易混淆的问题开始 -(void)OnNewFrameData:(NSData *)FrameData { UIImage * I = [UIImage imageWithData:FrameData]; [I release]; } 如果我不释放I,我会经历内存泄漏。然而,我从来没有保留过我。有人能解释这一点吗?框架数据完全由调用方管理 我还有一个关于保留财产的问题。使用上面相同的代码,将I分配给保留属性J,然后将nil分配给相同的保留属性,不
-(void)OnNewFrameData:(NSData *)FrameData
{
UIImage * I = [UIImage imageWithData:FrameData];
[I release];
}
如果我不释放I,我会经历内存泄漏。然而,我从来没有保留过我。有人能解释这一点吗?框架数据完全由调用方管理
我还有一个关于保留财产的问题。使用上面相同的代码,将I分配给保留属性J,然后将nil分配给相同的保留属性,不应该有任何泄漏,但我再次泄漏内存。我也可以释放保留的财产,但我还是有漏洞
@property (retain) UIImage * J;
...
-(void)OnNewFrameData:(NSData *)FrameData
{
UIImage * I = [UIImage imageWithData:FrameData];
self.J = I;
// I can also add here [self.J release]; and it still leaks...
self.J = nil;
[I release];
}
如果能从stackoverflow的文档和线程中了解到这两个令人困惑的明显矛盾,我将不胜感激。[UIImage imageWithData]是一种方便的方法,它可以实现如下功能
-(UIImage*)imageWithData:(NSData*)data{
UIImage *img = [[UIImage alloc] initWithData:data];
[img autorelease];
return img;
}
因此,正如您所看到的,有一个alloc设置,将retain count设置为1。希望这能澄清。如果我能进一步澄清,请留下评论。我刚刚收到提示,该图像将被放置在自动释放池中,如果您希望在池耗尽后将其持久化,则在创建时应保留该图像
正确的方法是使用
[[UIImage imageWithdata:data]retain];
进行此操作时,其保留计数将为2,这将在池排水时减少1。因此,您仍然只需要一个版本
p、 s您可能还需要运行分析仪。它将指出任何内存问题。CMD+shift+b
另一个想法。你能确认我不是零吗。文档说,如果创建UIImage失败,它将返回nil,这可能是个问题。因此我尝试了以下代码的实验
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
UIImage * Img = [[UIImage imageWithData:FrameData] retain];
[pool drain];
int n = [Img retainCount];
在上面的代码中,Img的保留计数返回1。如果我删除自动释放池,它是2。这绝对是imageWithData:返回自动释放对象的明确证据,这正是我们所期望的
因此,我唯一的结论是,池没有释放Img足够快,他们是池与每一个连续的图像来通过电线。最终我的记忆耗尽了
如果没有人对原始问题的第一部分有任何其他想法,我将不得不用这个作为答案
关于第二个问题,我仍然没有任何线索
更新:
一直让我困惑的是,主线程上标记为自动释放的对象是如何及时释放的?我一直认为,自动释放就像一个垃圾收集器,每当内存池内存不足时,它就会运行。但回顾文献,很明显GB并不是自动发布池的目的,因为它在非GB环境中可用。自动释放池不会释放任何对象,直到池被drain消息破坏
那么主线程对象呢?为什么在计划结束前它们不会累积?因为我在这里推测,但这是每次框架调用我们的类对象更新时最合乎逻辑的解释:我指的是框架在分派事件时调用我们的代码,它首先设置一个新的自动发布池。因此,框架对我们的类对象进行的任何方法调用中的所有对象都被一个新的池包围,当框架从我们的代码接收到控制返回时,所有标记为自动释放的对象都被释放
如果有任何人有任何信息可以进一步说明这一点,我非常希望听到您的消息。您如何确定内存是否泄漏?在两到三分钟后,我收到两个内存警告,1和2,然后程序通过iOS退出。视频帧的大小非常大,所以我认为它们正在消耗内存而没有被释放。我可以运行相同的代码大约半个小时,并且不会收到任何警告,表明我没有泄漏内存。有更好的方法吗?使用Xcode提供的instruments工具:instruments工具正在崩溃,并且根本没有指出我收到内存警告的原因。或者至少它的神秘信息没有给我多少线索。我不认为这是正确的,因为imageWithData:不是一个alloc、new或copy等命名方法,它应该返回一个自动释放的objectNo。不,不,不,不要碰-重新计数。假装那个方法不存在。我不在乎你在做什么,只是不在乎。我非常清楚访问retainCount的问题。我访问这里只是为了测试[pool drain]的行为,我们都假设它是来自imageWithData的autorelease对象引用。有趣的是,有人投票否决了我的答案,但无法用更好的解释解释解释我所看到的……你的猜测是错误的。默认情况下,主线程仅获取1个自动释放池,该池由nsrunlop创建。每次发送事件时,它都会创建一个新池。这里绝对没有类似GC的行为。自动释放
当对象周围的自动释放池被释放时,对象会被精确地销毁。这不是我说的吗?好的,我没有说分派事件,但我说的是每次框架调用我们的类对象时。我怀疑你的描述仅在措辞上更准确。。