子类化MKAnnotationView并从initWithFrame调用init时的无限循环:重载

时间:2015-07-24 14:42:00

标签: ios objective-c uiview

有这个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调用initinit调用initWithFrame

enter image description here

有人可以解释原因吗?

2 个答案:

答案 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