有这个XCTestCase案例:
- (void)testAllInitializersConfigureTheView {
BIStationAnnotationView *withFrame = [[BIStationAnnotationView alloc] initWithFrame:CGRectNull];
XCTAssertTrue(CGRectEqualToRect(withFrame.frame, CGRectMake(0.f, 0.f, 30.f, 40.f)), @"Frame should be fixed");
}
测试MKAnnotationView的子类:
- (id)init {
if (self = [super init]) {
self.frame = _myFrame;
}
return self;
}
- (instancetype)initWithFrame:(CGRect)frame {
return self = [self init];
}
- (instancetype)initWithCoder:(NSCoder *)coder {
return self = [self init];
}
我得到一个无限循环,因为initWithFrame
调用init
和init
调用initWithFrame
。
有人可以解释原因吗?
答案 0 :(得分:2)
我猜[UIView init]
正在调用[self initWithFrame:CGRectZero]
,因此您正在调用自己的initWithFrame
方法,因为您已经超载了它。
要解决您的问题,您应该这样做:)。
init
应该致电initWithFrame
,而不是相反。
答案 1 :(得分:1)
在Objective-C中,存在指定初始化程序的概念,它是最重要且通常最具体的初始化程序。此外,可能存在具有较短签名的便利初始化器,其在内部调用指定的初始化器。 Cocoa遵循这种模式,这意味着便利初始化器[UIView init]
调用指定的初始值设定项[UIView initWithFrame:]
。
在您的特定情况下,您从指定的初始化程序[self init]
调用便利初始值设定项[self initWithFrame:]
。这是错误的,因为[self init]
会调用[super init]
([UIView init]
),并且会遵循指定的初始化概念并调用[self initWithFrame]
。
要解决此问题,您应该从[super initWithFrame:]
内拨打[self initWithFrame:]
。
您可以在Apple的官方文档中了解有关此主题的更多信息:https://developer.apple.com/library/ios/documentation/General/Conceptual/CocoaEncyclopedia/Initialization/Initialization.html#//apple_ref/doc/uid/TP40010810-CH6-SW3