自包含 UIView 子类中的 UITapGestureRecognizer EXC_BAD_ACCESS
Posted
技术标签:
【中文标题】自包含 UIView 子类中的 UITapGestureRecognizer EXC_BAD_ACCESS【英文标题】:UITapGestureRecognizer EXC_BAD_ACCESS in self-contained UIView subclass 【发布时间】:2013-08-22 18:38:20 【问题描述】:我已经多次使用 UITapGestureRecognizer,但在这种情况下,当点击发生时,我会得到 EXC_BAD_ACCESS。我认为这与我将其添加到警报类型覆盖视图的事实有关。并且由于某种原因,即使在屏幕上,覆盖视图也没有得到保留。
我正在创建这样的视图:
HelperView *testHelper = [HelperView helperWithBodyText:@"test text"];
[testHelper presentAtPoint:screenCenter];
HelperView.m 中的便捷方法如下所示:
+ (id)helperWithBodyText:(NSString*)text
return [[self alloc] initWithFrame:CGRectZero bodyText:text];
其余代码如下所示:
- (id)initWithFrame:(CGRect)frame
self = [super initWithFrame:frame];
if (self)
self.container = [[AGWindowView alloc] initAndAddToKeyWindow];
self.container.supportedInterfaceOrientations = UIInterfaceOrientationMaskLandscapeRight;
self.overlay = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
self.overlay.backgroundColor = [UIColor redColor];
self.overlay.alpha = 0.6;
[self.container addSubviewAndFillBounds:self.overlay]; //this fills the screen with a transparent red color, for testing
UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissMe:)];
[self.overlay addGestureRecognizer:tap]; //I want to dismiss the whole view if the overlay is tapped
self.content = [[UIView alloc] initWithFrame:CGRectZero];
return self;
- (id)initWithFrame:(CGRect)frame bodyText:(NSString*)bodyText
self = [self initWithFrame:frame];
if (self)
//TEST frame
self.content.frame = CGRectMake(0, 0, 217, 134);
// Initialization code
UIImage *bgImage = [[UIImage imageNamed:@"helper-bg"]
resizableImageWithCapInsets:UIEdgeInsetsMake(30, 28, 20, 20)];
UIImageView *bgImgView = [[UIImageView alloc] initWithImage:bgImage];
bgImgView.bounds = self.content.frame;
[self.content addSubview:bgImgView];
return self;
- (void)presentAtPoint:(CGPoint)loc
CGPoint newPoint = [self.container convertPoint:loc toView:self.container];
self.content.center = newPoint;
[self.container addSubview:self.content];
- (void)dismissMe:(UITapGestureRecognizer*)recognizer
//this never happens - I get EXC_BAD_ACCESS when I tap the overlay
【问题讨论】:
【参考方案1】:HelperView 不是要显示的视图,也不会被保留,但您将其用作手势识别器的目标。 AGWindowView 属性“容器”由其超级视图显示和保留。您的代码需要重构,因为您有这个视图 HelperView,它本身不会显示任何内容,但是如果您希望它像这样工作,您需要保留 HelperView,这样它就不会自动释放。您可以通过将其分配给一个强实例变量来做到这一点。
【讨论】:
感谢您的信息。我就是这么想的。但是我希望在需要时创建这个 HelperView,并且我不希望每个视图控制器都需要一个强大的实例变量。例如 UIAlertView 不需要强实例变量。如何保持独立的视图? 另一个例子是:github.com/chrismiles/CMPopTipView。我查看了代码,但不知道它是如何保留的。 把[self.container addSubview:self.content]
改成[self.container addSubview:self]
就没事了,除了内存泄漏。
使HelperView
成为AGWindowView
的子类。删除container
属性,只需将所有子视图添加到self
。在您的初始化程序中将 self = [super initWithFrame:frame];
更改为 self = [super initAndAddToKeyWindow];
以上是关于自包含 UIView 子类中的 UITapGestureRecognizer EXC_BAD_ACCESS的主要内容,如果未能解决你的问题,请参考以下文章
子类 UIView 不显示添加到它的 UIImageViews
UIScrollView 中的 UIView 子类如何处理内存
自定义 UITableViewCell 中的自定义 UIView