Objective c 比较[类]不起作用?
我有一个单元测试:Objective c 比较[类]不起作用?,objective-c,unit-testing,introspection,ochamcrest,Objective C,Unit Testing,Introspection,Ochamcrest,我有一个单元测试: - (void)testFetchTrackByTrackIdIsATrack { [self addTrackWithSongId:@"123"]; Track *fetchedTrack = [self.library trackByTrackId:@"123"]; assertThat(fetchedTrack, instanceOf([Track class])); } 它失败于: file:///Users/elliot/Developme
- (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>
调试器报告:
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
类的地址随着时间的推移可能不是恒定的原因有很多,其中大多数归结为使用键值
当观察到一个实例时,运行时(基础框架,实际上)组成一个新的类,它是包含观察机制的实例原始类的子类。 这导致无法使用指针比较。这也意味着课堂上某些类型的内省将无法产生预期的结果
简言之;对于所有此类测试,请使用
isKindOfClass:
和isMemberOfClass:
方法,不要使用指针相等性测试(通常用于此测试或比较实例)。类的地址随时间变化可能不恒定的原因有很多,其中大多数归结为使用键值
当观察到一个实例时,运行时(基础框架,实际上)组成一个新的类,它是包含观察机制的实例原始类的子类。 这导致无法使用指针比较。这也意味着课堂上某些类型的内省将无法产生预期的结果
简言之;使用
isKindOfClass:
和isMemberOfClass:
方法进行所有此类测试,切勿使用指针相等性测试(通常用于此测试或比较实例)。参考:使用称为isa swizzling的技术实现自动键值观察。顾名思义,isa指针指向维护分派表的对象类。这个分派表本质上包含指向类实现的方法的指针以及其他数据。当一个观察者为一个对象的属性注册时,被观察对象的isa指针被修改,指向一个中间类而不是真正的类。因此,isa指针的值不一定反映实例的实际类。OCHamcrest中的instanceOf()
matcher使用isKindOfClass:
。我已经将显式测试添加到我的原始帖子中,以表明它仍然不起作用…@bbum但是class
return[super class]
的KVO子类实现不是在试图隐藏自己吗?在这种情况下,为什么返回的两个类指针不是相同的呢?@LeoNatan它并没有那么简单;在这两者之间可能有任意数量的旋转。有多种方法可以检索isa
。所有这些都是为什么我们应该使用API来查询这些精确的信息。参考:自动键值观察是使用一种称为isa swizzling的技术实现的。顾名思义,isa指针指向维护分派表的对象类。这个分派表本质上包含指向类实现的方法的指针以及其他数据。当一个观察者为一个对象的属性注册时,被观察对象的isa指针被修改,指向一个中间类而不是真正的类。因此,isa指针的值不一定反映实例的实际类。OCHamcrest中的instanceOf()
matcher使用isKindOfClass:
。我已经将显式测试添加到我的原始帖子中,以表明它仍然不起作用…@bbum但是class
return[super class]
的KVO子类实现不是在试图隐藏自己吗?在这种情况下,为什么返回的两个类指针不是相同的呢?@LeoNatan它并没有那么简单;在这两者之间可能有任意数量的旋转。有多种方法可以检索isa
。所有这些都是为什么我们应该使用API来查询这些精确的信息。
assertTrue(c1 == c2); // FAIL
assertThat([fetchedTrack classDescription],
equalTo([Track classDescription])); // PASS
assertTrue([fetchedTrack isKindOfClass:[Track class]]); // FAIL