わかった。initWithFrame:
コードの問題は、それがUIView
の指定された初期化メソッドであることを忘れていることです。したがって、[[Test alloc] init]
そのinit
呼び出しを呼び出しても、initWithFrame:
それ自体が呼び出されるため、無限ループが作成されます。
編集
iOS には、「指定された」初期化子の概念があります。いくつかの「init」メソッドがある場合は、そのうちの 1 つを「指定された」init にする必要があります。たとえば、UIView
の指定された初期化子はinitWithFrame
です。これは、他のすべての init メソッドが内部でそれを呼び出すことを意味します。
UIView
のinit
メソッドは次のようになります。
-(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: 考えられる回避策の 1 つ
これを防ぐためにできることの 1 つは、変数 (フラグ) を宣言して、それ自体のインスタンスをさらに作成し続ける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
お役に立てれば!