Бесконечный цикл при подклассификации MKAnnotationView и вызов init из initWithFrame: перегрузки

77
11

Имея этот случай 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.


введите описание изображения здесь


Может кто-нибудь объяснить, почему?

спросил(а) 2015-07-24T17:41:00+03:00 4 года, 10 месяцев назад
1
Решение
54

В 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

ответил(а) 2015-07-24T18:04:00+03:00 4 года, 10 месяцев назад
66

Я предполагаю, что [UIView init] вызывает [self initWithFrame:CGRectZero], поэтому он вызывает ваш собственный метод initWithFrame, так как вы перегрузили его.

Чтобы решить свои проблемы, вы должны просто сделать то же самое:).
init должен вызывать initWithFrame, а не наоборот.

ответил(а) 2015-07-24T17:49:00+03:00 4 года, 10 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема