Сравнение [класс] не работает?

У меня есть юнит-тест:

- (void)testFetchTrackByTrackIdIsATrack
{
    [self addTrackWithSongId:@"123"];
    Track *fetchedTrack = [self.library trackByTrackId:@"123"];
    assertThat(fetchedTrack, instanceOf([Track class]));
}

Который терпит неудачу с:

file:///Users/elliot/Development/Hark/HarkTests/TestLibrary.m: test failure:
-[TestLibrary testFetchTrackByTrackIdIsATrack] failed: Expected an instance
of Track, but was Track instance <Track: 0x6180001077d0>

У меня есть несколько других тестов, которые используют одинаковые проверки экземпляров на разных классах, которые работают, но я не могу понять, почему это не работает. Копаться глубже:

- (void)testFetchTrackByTrackIdIsATrack
{
    [self addTrackWithSongId:@"123"];
    Track *fetchedTrack = [self.library trackByTrackId:@"123"];
    Class c1 = [fetchedTrack class];
    Class c2 = [Track class];
}

Отчеты отладчика:

c1  Class   Track           0x0000000100012fe0
c2  Class   0x1000b3eb8     0x00000001000b3eb8

Обратите внимание, что он не может видеть это [Track class] это класс типа Track? Когда я применяю ту же логику к другим проходящим модульным тестам, они оба сообщают правильное имя класса.

Такое ощущение, что у него нет метаданных класса во время выполнения, но почему?

Еще несколько случаев:

assertTrue(c1 == c2);                                   // FAIL
assertThat([fetchedTrack classDescription],
  equalTo([Track classDescription]));                   // PASS
assertTrue([fetchedTrack isKindOfClass:[Track class]]); // FAIL

1 ответ

Существует множество причин, по которым адрес класса может не быть постоянным во времени, и большинство из них сводятся к использованию наблюдения значения ключа.

Когда наблюдается экземпляр, среда выполнения (на самом деле, платформа Foundation) создает новый класс, который является подклассом исходного класса экземпляра, который содержит механизмы наблюдения.

Это приводит к невозможности использовать указатель сравнения. Это также означает, что некоторые типы самоанализа класса не дадут ожидаемых результатов.

Короче; использовать isKindOfClass: а также isMemberOfClass: методы для всех таких тестов и никогда не использовать тестирование на равенство указателей (для этого или для сравнения экземпляров в целом).

Другие вопросы по тегам