我一直在努力解决一个错误,我找到了解决办法,但我想了解究竟发生了什么。它与UIButton目标操作有关,这取决于子类内部的不同子视图层次结构。
简要总结:我有一个NSObject的子类,它有一个UIView属性对象,一个UIButton附加到它上面,一个目标被添加到调用子类内部函数的按钮中。在主ViewController中,我初始化子类并将其视图添加到视图堆栈,单击按钮,它将我抛给main.mm并显示错误 - EXC_BAD_ACCESS,给我一些反馈。层次结构如下所示:
-CustomClass
--UIView <-this is added as a subview to the View Controller
---UIButton (onRelease calling a function)
所以我通过将自定义类更改为UIView的子类而不是NSObject来修复它,然后将其@property UIView添加为自定义类的子视图(并且按钮仍然附加到子视图),然后在主View Controller中,我将自定义类本身添加为子视图,而不是类的子视图属性对象。然后按钮成功调用该函数。所以新的安排看起来像这样:
-CustomClass (now UIView) <-this is added as a subview to the View Controller
--UIView <-this is added as a subview to CustomClass
---UIButton (onRelease calling a function)
然后,我意识到我可以将CustomClass保留为两个实例的UIView的子类,如果其他所有内容都没有改变,问题仍然存在于原始设置中。
好的,更详细,这里的代码:
CustomClass: .H
@interface Temp : UIView
@property UIView *subview;
@property UIButton *but;
@end
的.m
-(id) init{
self = [super initWithFrame:[[UIScreen mainScreen] bounds]];
if(self){
_subview = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
//[self addSubview:_subview]; // FOR THE FIX
_but = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[_but setTitle:@"OKAY" forState:UIControlStateNormal];
[_but setBackgroundColor:[UIColor blackColor]];
[_but setFrame:CGRectMake(50, 50, 200, 200)];
[_subview addSubview:_but];
[_but addTarget:self action:@selector(pageTurn) forControlEvents:UIControlEventTouchUpInside];
}
return self;
}
-(void) pageTurn{
NSLog(@"WORKS");
}
内部视图控制器:
Temp *temp = [[Temp alloc] init];
[self.view addSubview:temp.subview];
//[self.view addSubview:temp]; // FOR THE FIX, instead of above line
答案 0 :(得分:0)
您正在弄乱您不需要的各种视图层次结构,这可能是导致问题的原因。我创建了一个 Test UIView子类,它有一个UIButton实例变量,我在Test对象中添加了一个子视图,不需要添加另一个视图作为子视图,然后添加按钮到子视图,然后在视图控制器中将按钮的子视图添加到视图中 - 它的方式比它需要的更复杂。
简而言之 - 创建Temp UIView,将按钮添加为子视图,然后在视图控制器类中添加Temp UIView作为子视图。很简单,这是代码:
- (id)init {
self = [super initWithFrame:[[UIScreen mainScreen] bounds]];
if(self){
_but = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[_but setTitle:@"OKAY" forState:UIControlStateNormal];
[_but setBackgroundColor:[UIColor blackColor]];
[_but setFrame:CGRectMake(100, 100, 200, 200)];
[_but addTarget:self action:@selector(pageTurn) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:_but];
}
return self;
}
- (void)pageTurn {
NSLog(@"WORKS");
}
然后向我的视图控制器添加了一个实例:
Test *temp = [[Test alloc] init];
temp.backgroundColor = [UIColor redColor];
[self.view addSubview:temp];
这是结果:
答案 1 :(得分:0)
谁持有temp
?
如果任何人都没有引用temp
,那么它就会被释放。那时目标是僵尸,当然你会崩溃。 temp.subview
正在追踪self.view
。
在第二个设置中,添加temp
作为self.view
的子视图会保留对它的引用。
您可以通过在视图控制器中添加Temp *
属性来解决此问题。
self.temp = [[Temp alloc] init];
[self.view addSubview:self.temp.subview];