Ordem de método de carregamento alterada no Xcode 7

Eu descobri que o Xcode 7 (Versão 7.0 (7A220)) mudou a ordem em que+load métodos para classes e categorias são chamados durante testes de unidade.

Se uma categoria pertencente ao alvo de teste implementar um+load agora é chamado no final, quando instâncias da classe já podem ter sido criadas e usadas.

eu tenho umAppDelegate, que implementa+load método. oAppDelegate.m arquivo também contémAppDelegate (MainModule) categoria. Além disso, há um arquivo de teste de unidadeLoadMethodTestTests.m, que contém outra categoria -AppDelegate (UnitTest).

Ambas as categorias também implementam+load método. A primeira categoria pertence ao alvo principal, a segunda - ao alvo de teste.

Código

Eu fiz um pequenoprojeto de teste para demonstrar o problema. Trata-se de um projeto Xcode padrão vazio, com apenas dois arquivos alterados.

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

E um arquivo de teste de unidade (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
Testando

Eu realizei o teste de unidade deste projeto (o código e o link do github estão abaixo) no Xcode 6/7 e obtive o seguinte+load ordem de chamadas:

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
Pergunta, questão

Xcode 7 executa a categoria de destino de teste+load método (Unit Test +load) no final, após oAppDelegate já foi criado.É um comportamento correto ou é um bug que deve ser enviado à Apple?

Pode não estar especificado, portanto, o compilador / tempo de execução é livre para reorganizar as chamadas? Eu dei uma olhadaesta pergunta SO bem como no+ descrição da carga na documentação do NSObject mas eu não entendi direito como+load O método deve funcionar quando a categoria pertence a outro destino.

Ou talvezAppDelegate há algum tipo de caso especial por algum motivo?

Por que estou perguntando issoFinalidade educacional.Eu costumava executar o método swizzling em uma categoria dentro do alvo do teste de unidade. Agora, quando a ordem de chamada for alterada,applicationDidFinishLaunchingWithOptions é realizado antes do swizzling ocorrer. Acredito que existem outras maneiras de fazer isso, mas me parece contra-intuitivo o modo como funciona no Xcode 7. Pensei que quando uma classe é carregada na memória,+load desta classe e+load métodos de todas as suas categorias devem ser chamados antes que possamos algo com essa classe (como criar uma instância e chamardidFinishLaunching...)

questionAnswers(2)

yourAnswerToTheQuestion