Изменен + порядок загрузки метода в Xcode 7
Я узнал, что Xcode 7 (версия 7.0 (7A220)) изменил порядок, в котором+load
методы для классов и категорий вызываются во время юнит-тестов.
Если категория, принадлежащая цели теста, реализует+load
метод, теперь он вызывается в конце, когда экземпляры класса, возможно, уже были созданы и использованы.
у меня естьAppDelegate
, который реализует+load
метод.AppDelegate.m
файл также содержитAppDelegate (MainModule)
категория. Кроме того, есть файл модульного тестаLoadMethodTestTests.m
, который содержит другую категорию -AppDelegate (UnitTest)
.
Обе категории также реализуют+load
метод. Первая категория относится к основной цели, вторая - к контрольной цели.
Я сделал маленькийтестовый проект продемонстрировать проблему. Это пустой проект по умолчанию Xcode one view с измененными только двумя файлами.
AppDelegate.m:
#import "AppDelegate.h"
@implementation AppDelegate
+(void)load {
NSLog(@"Class load");
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSLog(@"didFinishLaunchingWithOptions");
return YES;
}
@end
@interface AppDelegate (MainModule)
@end
@implementation AppDelegate (MainModule)
+(void)load {
NSLog(@"Main Module +load");
}
@end
И файл модульного теста (LoadMethodTestTests.m):
#import <UIKit/UIKit.h>
#import <XCTest/XCTest.h>
#import "AppDelegate.h"
@interface LoadMethodTestTests : XCTestCase
@end
@interface AppDelegate (UnitTest)
@end
@implementation AppDelegate (UnitTest)
+(void)load {
NSLog(@"Unit Test +load");
}
@end
@implementation LoadMethodTestTests
-(void)testEmptyTest {
XCTAssert(YES);
}
@end
тестированиеЯ выполнил модульное тестирование этого проекта (код и ссылка на github ниже) на Xcode 6/7 и получил следующее+load
порядок звонков:
Xcode 6 (iOS 8.4 simulator):
Unit Test +load
Class load
Main Module +load
didFinishLaunchingWithOptions
Xcode 7 (iOS 9 simulator):
Class load
Main Module +load
didFinishLaunchingWithOptions
Unit Test +load
Xcode 7 (iOS 8.4 simulator):
Class load
Main Module +load
didFinishLaunchingWithOptions
Unit Test +load
ВопросXcode 7 запускает целевую категорию теста+load
метод (Unit Test +load
) в конце концов, послеAppDelegate
уже был создан.Это правильное поведение или это ошибка, которую следует отправить в Apple?
Может быть, он не указан, поэтому компилятор / среда выполнения могут свободно переставлять вызовы? Я посмотрел наэтот ТАК вопрос а также на+ описание загрузки в документации NSObject но я не совсем понял, как+load
Метод должен работать, когда категория принадлежит другой цели.
Или, может бытьAppDelegate
это какой-то особый случай по какой-то причине?
applicationDidFinishLaunchingWithOptions
выполняется до того, как произойдет бурение. Я верю, что есть и другие способы сделать это, но мне просто кажется нелогичным то, как это работает в Xcode 7. Я подумал, что когда класс загружается в память,+load
этого класса и+load
методы всех его категорий должны вызываться до того, как мы сможем что-то с этим классом (например, создать экземпляр и вызватьdidFinishLaunching...
).