如果我稍后会检测到触摸,我是否应该将UIImageView添加到我的视图中?

时间:2011-02-06 22:31:44

标签: iphone objective-c sdk uiimageview release

我已经了解到,如果您创建了一个对象,那么您拥有它并需要在完成后释放它。在这种情况下,我创建一个UIImageView并将其添加到我的视图中:

myImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"image.png"]];
[myImageView setFrame:CGRectMake(10,10,100,100)];
[self.view addSubview:myImageView]; 
[myImageView release];

如果我以后想要在我的touchEnded方法中检测myImageView上的触摸:

if([touch view] == myImageView){
    NSLog(@"TOUCHED!");
}

这是有效的,但是这是正确的,因为我现在在释放后使用了myImageView吗? 如何从我之前添加的self.view中发布myImageView?

5 个答案:

答案 0 :(得分:1)

Cocoa内存管理的基本规则是你应该保留你关心的东西,并释放你不关心​​的东西。有一些非常少的异常可以防止保留循环(从不保留委托和数据源),但这是您应该遵循的规则。

在这种情况下,如果您将图像存储在ivar中,我将继续保留它,无论其超级视图是否始终保留它,因此您不会“拥有”。但是如果从超级视图中移除视图,你将会看到一个悬空指针,然后你会崩溃,所以我通过保留来防御性地编码。如果你在这里使用了一个访问器(你应该使用),那么这将是自动的,更加安全。

Apple在iOS中对此更加一致,转而推荐有关IBOutlets的建议。在Mac上,您不会保留您的IBOutlets,但在iOS,Apple explicitly instructs中您可以保留它。这与您正在讨论的情况类似,我同意Apple采取更安全的方法。

答案 1 :(得分:1)

只要您的myUIImageView对象具有保留计数> 0,它仍然存在,你可以继续使用它。当您第一次将其添加为子视图时,它会获得一条保留消息,因此它的保留计数很可能为2.然后您将其发送给它,因此其保留计数减少为1.这意味着它仍然存在于内存中。现在,如果你再次发送它,或者发送它removeFromSuperView,那么它的保留计数将为零,你就会丢失它。

答案 2 :(得分:0)

行为不稳定,有时你可能会看到它有效,有时你会崩溃。

如果要使用该变量指向图像视图,请保留ivar(使用retain属性)。这样可以确保图像视图可供控制器类使用。

答案 3 :(得分:0)

假设myUIImageView是您的自定义UIView子类的ivar,只要您的图像视图保留在他的超级视图中,您的代码就会起作用。可以释放图像视图实例,并且可以以引用解除分配的对象的无效指针结束。你最好崩溃。

根据内存管理指南,您应该考虑图像视图< - >自定义uiview子类关系asher:

  • 强烈参考。您拥有图像视图(在创建时),并负责保留/释放它
  • 弱参考。您不拥有该对象,因此保留对它的引用可能是危险的。

在你的情况下,它可能是一个强有力的参考。你的myUIImageView ivar应该是你对象的非原子保留属性。

答案 4 :(得分:0)

如果您需要在将来的某个时间点访问UIImage,则需要保留它。

如何执行此操作由您自行决定,但您依靠UIView为您重新训练对象。你创造的情况现在适用,但它很脆弱。