首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >isKindOfClass意外返回NO

isKindOfClass意外返回NO
EN

Stack Overflow用户
提问于 2012-08-28 21:08:33
回答 9查看 4.6K关注 0票数 18

我的一个单元测试失败了,因为一个我没有预料到的原因。对isKindOfClass的调用似乎返回NO,但当我调试并单步执行时,似乎没有任何理由会返回no。

代码是:

代码语言:javascript
复制
if ([self.detailItem isKindOfClass:[MovieInfo class]]) {
    [self configureViewForMovie];
}

我一步一步地完成了代码:

代码语言:javascript
复制
po self.detailItem

这将显示:

代码语言:javascript
复制
(id) $1 = 0x0ea8f390 <MovieInfo: 0xea8f390>

那么,我遗漏了什么,为什么if语句在这种情况下会返回false?

编辑:

下面是DetailItem的设置器:

代码语言:javascript
复制
- (void)setDetailItem:(id)newDetailItem
{
    if (_detailItem != newDetailItem) {
        NSLog(@"%@", [newDetailItem class]);
        _detailItem = newDetailItem;

        // Update the view.
        [self configureView];
    }

    if (self.masterPopoverController != nil) {
        [self.masterPopoverController dismissPopoverAnimated:YES];
    } 
}

它是来自Master Detail模板的模板代码。

单元测试在setUp中创建一个MovieInfo:

代码语言:javascript
复制
movie = [[MovieInfo alloc] initWithMovieName:@"Movie" movieID:1];

并将其设置在测试中

代码语言:javascript
复制
controller.detailItem = movie;

此外,我在setDetailItem中添加了一个参数断言

代码语言:javascript
复制
NSParameterAssert([newDetailItem isKindOfClass:[MovieInfo class]] || [newDetailItem isKindOfClass:[PersonInfo class]] || newDetailItem == nil);

这种断言也是失败的。

我将两个日志语句放在断言调用之上:

代码语言:javascript
复制
NSLog(@"%@", [newDetailItem class]);
NSLog(@"%@", newDetailItem);

显示以下内容:

代码语言:javascript
复制
2012-08-28 08:31:37.574 Popcorn[8006:c07] MovieInfo
2012-08-28 08:31:38.253 Popcorn[8006:c07] <MovieInfo: 0x6daac50>

再编辑一次:

在单元测试中设置之前,我添加了isKindOfClass检查,这个检查通过了。

代码语言:javascript
复制
if ([movie isKindOfClass:[MovieInfo class]]) {
    NSLog(@"Yep"); //This passes and prints out
}
controller.detailItem = movie; //calls into the setter and fails.
EN

回答 9

Stack Overflow用户

回答已采纳

发布于 2012-08-28 22:13:44

这是因为被测试的类"DetailViewController“不在测试的目标中。我本以为这会以一种不同的方式表现出来(链接器错误或其他),但很明显,它只是导致了奇怪的行为。将DetailViewController添加到测试目标修复了这些问题。

票数 16
EN

Stack Overflow用户

发布于 2012-08-28 21:13:23

我怀疑是竞争条件,或者是Debug和Release配置之间的不同。这将导致调试器和常规运行时之间的差异。

首先,确保self.detailItem不是nil。这是此类问题最常见的原因。然后尝试使用日志而不是调试器对其进行调试。如果您确实有竞争条件,那么您还可以考虑使用printf()而不是NSLog()进行日志记录。printf()是一种对性能影响小得多的多线程日志记录方式。

票数 2
EN

Stack Overflow用户

发布于 2014-08-07 00:57:40

我在我正在写的一个库中遇到了同样的问题。有趣的是,它在我的iOS测试目标上工作得很好,但在Mac测试目标上却失败了(有趣!)。

我认为这个问题与类声明中的不匹配有关。该库使用了.h声明,但单元测试查看的是内部声明。

用一个例子来解释会更容易:

代码语言:javascript
复制
/*
 * ClassA.h
 */
@interface ClassA () : NSObject

@property (nonatomic, strong, readonly) NSString *someValue1;
@property (nonatomic, strong, readonly) NSString *someValue2;
@property (nonatomic, strong, readonly) NSString *someValue3;

@end

添加到.m中的属性列表

代码语言:javascript
复制
/*
 * ClassA.m
 */
@interface ClassA () : NSObject

@property (nonatomic, strong, readwrite) NSString *someValue2;
@property (nonatomic, strong, readwrite) NSDate *date;
@property (nonatomic, strong, readwrite) NSDateFormatter *dateFormatter;

@end

@implementation 
// implementation
@end

现在,由于单元测试目标将编译源代码设置为包含ClassA.m,因此isKindOfClass:将返回no,但是在调试器中运行po命令和NSStringFromClass([ClassA class])时,将返回您所期望的值。

我知道这是一个古老的帖子,但我希望这是有用的,并节省了很多人的时间。我花了将近一个小时才弄明白这个问题!

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12159961

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档