我现在明白了。initWithFrame:
您的代码的问题是您忘记了UIView
指定的初始化方法。因此,即使您调用[[Test alloc] init]
该init
调用也会调用initWithFrame:
自身,从而创建一个无限循环。
编辑
在 iOS 中有一个“指定”初始化程序的概念。每当您有多个“init”方法时,您都必须将其中一个设为“指定”init。例如,UIView
的指定初始值设定项是initWithFrame
。这意味着所有其他 init 方法都会在后台调用它,即使是 init。
这是UIView
'sinit
方法的样子:
-(id)init {
return [self initWithFrame:CGRectMake(0,0,0,0)];
}
这意味着即使您将您的类实例化为 [[Test alloc] init],initWithFrame
仍然会被UIView
.
initWithFrame:
现在,您在您的类中覆盖,Test
并且您还在该方法中创建另一个Test
实例,该方法再次调用initWithFrame:
// the init call you have inside this method is calling initWithFrame again beacause
// you're referring to the same Test class...
-(id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
// This line here is creating the infinite loop. Right now you're inside
// Test's initWithFrame method. Here you're creating a new Test instance and
// you're calling init... but remember that init calls initWithFrame, because
// that's the designated initializer. Whenever the program hits this line it will
// call again initWithFrame which will call init which will call initWithFrame
// which will call init... ad infinitum, get it?
Test *test = [[Test alloc] init];
[test setFrame:frame];
[test setBackgroundColor:[UIColor redColor]];
[self addSubview:test];
}
}
EDIT2:一种可能的解决方法
为了防止这种情况,您可以做的一件事是声明一个static bool
变量(标志)来指示是否Test
应该继续创建更多自身的实例:
static BOOL _keepCreating = YES;
@implementation Test
-(id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
// Remember to set _keepCreating to "NO" at some point to break
// the loop
if (_keepCreating)
{
Test *test = [[Test alloc] init];
[test setFrame:frame];
[test setBackgroundColor:[UIColor redColor]];
[self addSubview:test];
}
}
}
@end
希望这可以帮助!