如果稍后检测到触摸,我是否应该释放添加到我的视图中的 UIImageView?
我了解到,如果您创建了一个对象,您就拥有它,并且需要在使用完毕后释放它。在这种情况下,我创建一个 UIImageView 并将其添加到我的视图中,如下所示:
myImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"image.png"]];
[myImageView setFrame:CGRectMake(10,10,100,100)];
[self.view addSubview:myImageView];
[myImageView release];
如果我稍后想要在 touchEnded-method 中检测到 myImageView 上的触摸:
if([touch view] == myImageView){
NSLog(@"TOUCHED!");
}
这可行,但这是正确的,因为我现在在释放 myImageView 后使用它? 如何从我之前添加到的 self.view 中释放 myImageView ?
I've learnt that if you create an object, you own it and need to release it when you're done with it. In this case I create an UIImageView and add it to my view like this:
myImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"image.png"]];
[myImageView setFrame:CGRectMake(10,10,100,100)];
[self.view addSubview:myImageView];
[myImageView release];
If I later on want to detect touch on myImageView like this in my touchEnded-method:
if([touch view] == myImageView){
NSLog(@"TOUCHED!");
}
This works, but is this correct, since I now used myImageView after releasing it?
And how do I release myImageView from the self.view that I added it to earlier?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
Cocoa内存管理的基本规则是你应该保留那些你关心的东西,并释放那些你不关心的东西。有极少数例外情况可以防止保留循环(委托和数据源永远不会被保留),但这是您应该遵循的规则。
在这种情况下,如果您将图像存储在 ivar 中,我将继续保留它,不管它的超级视图将始终保留它,所以您“不必”这样做。但是,如果视图从其超级视图中删除,您将得到一个悬空指针,然后您将崩溃,因此我通过保留来防御性地编写代码。如果您在这里使用了访问器(您应该这样做),那么这将是自动的并且更安全。
Apple 在 iOS 中对此变得更加一致,改变了对 IBOutlet 的推荐。在 Mac 上,您不保留 IBOutlet,但在 iOS 中,Apple 明确指示您这样做。这与你正在讨论的情况类似,我同意苹果采取更安全的做法。
The cardinal rule of Cocoa memory management is that you should retain those things you care about, and release those things you do not care about. There are a very small number of exceptions to prevent retain loops (delegates and datasources are never retained), but this is the rule you should follow.
In this case, if you are storing the image in an ivar, I would continue to retain it, regardless of the fact that its superview will always retain it, and so you don't "have" to. But if the view is removed from its superview, you will wind up with a dangling pointer, and then you will crash, so I code defensively against that by retaining. If you used an accessor here (which you should), then this would be automatic and much safer.
Apple has grown more consistent about this in iOS, switching their recommendation about IBOutlets. On Mac, you do not retain your IBOutlets, but in iOS, Apple explicitly instructs you to do so. This is similar to the situation you are discussing, and I agree with Apple's move towards a safer approach.
只要你的 myUIImageView 对象有一个保留计数 > 0,它仍然存在,您可以继续使用它。当你第一次将它添加为子视图时,它会收到一条保留消息,因此它的保留计数可能为 2。然后你向它发送释放,因此它的保留计数会减少到 1。这意味着它仍然存在于内存中。现在,如果您再次发送它release,或者发送它
removeFromSuperView
,那么它的保留计数将为零,并且您将丢失它。As long as your myUIImageView object has a retain count > 0, it will still exist and you can continue using it. When you first add it as a subview, it gets a retain message so it's retain count is likely 2. Then you send it release, so its retain count is reduced to 1. This means it still exists in memory. Now, if you sent it release again, or sent it
removeFromSuperView
then its retain count would be zero, and you'd lose it.该行为不稳定,有时您可能会看到它有效,有时您会崩溃。
如果您想使用该变量指向图像视图,请保留 ivar(通过使用
retain
属性)。这样您就可以确保图像视图可供您的控制器类使用。The behavior is erratic, sometimes you may see it works, sometimes you get a crash.
If you want to use that variable to point to your image view, retain the ivar (by using a
retain
property). This way you ensure that the image view is available for your controller class to use.假设 myUIImageView 是您的自定义 UIView 子类的 ivar,只要您的图像视图保留在其超级视图中,您的代码就可以工作。图像视图实例可能会被释放,并且您可能会以引用已释放对象的无效指针结束。充其量你会崩溃。
根据内存管理指南,您应该考虑您的图像视图<->自定义 uiview 子类关系为wether:
就你而言,这可能是一个强有力的参考。你的 myUIImageView ivar 应该是你的对象的非原子保留属性。
Assuming myUIImageView is an ivar of your custom UIView subclass, your code will work as long as your image view stays in his superview. The image view instance may be deallocated and you may end with an invalid pointer referencing a deallocated object. At best you crash.
According to memory management guidelines, you should consider your image view <-> custom uiview subclass relation as wether:
in your case, it's probably a strong reference. your myUIImageView ivar should be a nonatomic retained property of your object.
如果您需要在将来某个时候访问您的
UIImage
,则需要保留它。如何执行此操作由您自行决定,但您不应该 依靠 UIView 来为您重新训练对象。您所创造的情况目前有效,但很脆弱。
If you need to access your
UIImage
at some point in the future, you need to retain it.How you do this is at your discretion, but you should not rely on the UIView to retrain your objects for you. The situation you've created works for now, but it's fragile.