简体   繁体   English

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

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

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: 在这种情况下,我创建一个UIImageView并将其添加到我的视图中,如下所示:

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: 如果以后我想在我的touchEnded方法中像这样检测myImageView上的触摸:

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

This works, but is this correct, since I now used myImageView after releasing it? 这行得通,但这是正确的,因为我现在在发布myImageView之后使用了它? And how do I release myImageView from the self.view that I added it to earlier? 如何从我之前添加的self.view中释放myImageView?

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. Cocoa内存管理的基本原则是,您应该保留那些您关心的东西,并释放那些您不关心的东西。 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. 在这种情况下,如果您将图像存储在ivar中,我将继续保留它,无论其superview将始终保留它,因此您不必“拥有”。 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. 苹果公司在iOS中对此变得越来越一致,从而改变了他们对IBOutlets的建议。 On Mac, you do not retain your IBOutlets, but in iOS, Apple explicitly instructs you to do so. 在Mac上,您不保留IBOutlets,但在iOS中,Apple 明确指示您这样做。 This is similar to the situation you are discussing, and I agree with Apple's move towards a safer approach. 这与您正在讨论的情况类似,我同意Apple采取更安全方法的举动。

As long as your myUIImageView object has a retain count > 0, it will still exist and you can continue using it. 只要myUIImageView对象的保留计数> 0,它仍然存在,您可以继续使用它。 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. 当您第一次将其添加为子视图时,它会获得一条保留消息,因此它的保留计数很可能为2.然后您将其发送给它,因此其保留计数减少为1.这意味着它仍然存在于内存中。 Now, if you sent it release again, or sent it removeFromSuperView then its retain count would be zero, and you'd lose it. 现在,如果你再次发送它,或者发送它removeFromSuperView那么它的保留计数将为零,你就会失去它。

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). 如果要使用该变量指向图像视图,请保留ivar(使用retain属性)。 This way you ensure that the image view is available for your controller class to use. 这样,您可以确保图像视图可供控制器类使用。

Assuming myUIImageView is an ivar of your custom UIView subclass, your code will work as long as your image view stays in his superview. 假设myUIImageView是您的自定义UIView子类的ivar,只要您的图像视图保留在他的超级视图中,您的代码就会起作用。 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: 根据内存管理指南,您应该将您的图像视图< - >自定义uiview子类关系视为更好:

  • strong reference. 有力的参考。 You own the image view (as you created it), and are responsible for retaining / releasing it 您拥有图像视图(在创建时),并负责保留/释放它
  • weak reference. 参考薄弱。 You don't own the object, thus keeping a reference to it may be dangerous. 您不拥有该对象,因此保留对它的引用可能是危险的。

in your case, it's probably a strong reference. 就您而言,这可能是一个很好的参考。 your myUIImageView ivar should be a nonatomic retained property of your object. 你的myUIImageView ivar应该是你对象的非原子保留属性。

If you need to access your UIImage at some point in the future, you need to retain it. 如果您需要在将来某个时间访问UIImage ,则需要保留它。

How you do this is at your discretion, but you should not rely on the UIView to retrain your objects for you. 你怎么做,这是你的自由裁量权,但你应该依靠的UIView重新培训你的对象为您服务。 The situation you've created works for now, but it's fragile. 你创造的情况现在适用,但它很脆弱。

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

相关问题 如何检测 UIImageView 的触摸事件? - How can I detect the touch event of an UIImageView? 如何在视图上添加触摸和检测UIImageView,这样我可以移动它而不是在它上面添加一个? - how to add on touch and detect UIImageView on view so i could move it around and not adding one on top of it? 如何在自定义视图中检测到内部的触摸? - How can I detect a touch up inside in my custom view? 如何在touchesBegan中通过触摸检测选择了哪个UIImageView? - How can I detect which UIImageView was selected with a touch in touchesBegan? 从视图控制器检测触摸是否在移动的UIImageView上 - Detect if a touch is on a moving UIImageView from a View Controller 如何使用滚动视图检测触摸? - how can i detect a touch with a scroll view? 在对UIImageView进行旋转之后,我应该如何检查触摸点是否在UIImageView区域内? - After rotation being made to UIImageView, how should I check if a touch point is inside the UIImageView region? 在UIScrollView中的UIImageView中检测触摸 - Detect touch in UIImageView in UIScrollView 将滚动事件传递给uiviewview中的uiimageview,并将其添加为要查看的子视图 - Passing touch events to uiimageview within a scrollview added as subview to view 什么时候应该发布我的阵列? - When should I release my array?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM