繁体   English   中英

如果以后会检测到触摸,应否发布添加到视图的UIImageView?

[英]Should I release an UIImageView added to my view if I will detect touch on it later on?

我了解到,如果您创建了一个对象,那么您将拥有它,并在完成处理后需要释放它。 在这种情况下,我创建一个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?

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

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

苹果公司在iOS中对此变得越来越一致,从而改变了他们对IBOutlets的建议。 在Mac上,您不保留IBOutlets,但在iOS中,Apple 明确指示您这样做。 这与您正在讨论的情况类似,我同意Apple采取更安全方法的举动。

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

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

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

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

根据内存管理指南,您应该将您的图像视图< - >自定义uiview子类关系视为更好:

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

就您而言,这可能是一个很好的参考。 你的myUIImageView ivar应该是你对象的非原子保留属性。

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

你怎么做,这是你的自由裁量权,但你应该依靠的UIView重新培训你的对象为您服务。 你创造的情况现在适用,但它很脆弱。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM