继承 MKAnnotationView 并从 initWithFrame 调用 init 时无限循环:重载
Infinite loop when subclassing MKAnnotationView and calling init from initWithFrame: overloads
有这个 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
。
有人可以解释为什么吗?
我猜 [UIView init]
正在调用 [self initWithFrame:CGRectZero]
,所以它正在调用您自己的 initWithFrame
方法,因为您已经重载了它。
要解决你的问题,你应该简单地做同样的事情:)。
init
应该调用 initWithFrame
而不是相反。
在Objective-C中有指定初始化器的概念,它是最重要的,通常也是最具体的初始化器。此外,可能存在带有较短签名的便利初始化器,它们在内部调用指定的初始化器。 Cocoa 遵循此模式,这意味着便利初始化程序 [UIView init]
调用指定初始化程序 [UIView initWithFrame:]
.
在您的特定情况下,您从指定的初始值设定项 [self initWithFrame:]
调用便利初始值设定项 [self init]
。这是错误的,因为 [self init]
将调用 [super init]
(即 [UIView init]
)并且那个遵循指定的初始化概念并调用 [self initWithFrame]
.
要解决此问题,您应该从 [self initWithFrame:]
.
中调用 [super initWithFrame:]
您可以在 Apple 的官方文档中阅读有关此主题的更多信息:https://developer.apple.com/library/ios/documentation/General/Conceptual/CocoaEncyclopedia/Initialization/Initialization.html#//apple_ref/doc/uid/TP40010810-CH6-SW3
有这个 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
。
有人可以解释为什么吗?
我猜 [UIView init]
正在调用 [self initWithFrame:CGRectZero]
,所以它正在调用您自己的 initWithFrame
方法,因为您已经重载了它。
要解决你的问题,你应该简单地做同样的事情:)。
init
应该调用 initWithFrame
而不是相反。
在Objective-C中有指定初始化器的概念,它是最重要的,通常也是最具体的初始化器。此外,可能存在带有较短签名的便利初始化器,它们在内部调用指定的初始化器。 Cocoa 遵循此模式,这意味着便利初始化程序 [UIView init]
调用指定初始化程序 [UIView initWithFrame:]
.
在您的特定情况下,您从指定的初始值设定项 [self initWithFrame:]
调用便利初始值设定项 [self init]
。这是错误的,因为 [self init]
将调用 [super init]
(即 [UIView init]
)并且那个遵循指定的初始化概念并调用 [self initWithFrame]
.
要解决此问题,您应该从 [self initWithFrame:]
.
[super initWithFrame:]
您可以在 Apple 的官方文档中阅读有关此主题的更多信息:https://developer.apple.com/library/ios/documentation/General/Conceptual/CocoaEncyclopedia/Initialization/Initialization.html#//apple_ref/doc/uid/TP40010810-CH6-SW3