【问题标题】:Objective-C NSArray, Block, STAssertEqualsObjective-C NSArray,块,STAssertEquals
【发布时间】:2013-03-08 12:58:40
【问题描述】:

我正在开发一个应用程序,该应用程序列出了一项运动的当前现场比赛。使用 REST 从远程源获取有关实时游戏的信息。第一个请求给出了一个带有他们的 id 和相应的竞技场 id 的现场游戏列表。然后我必须从他们的 id 中获取竞技场名称。当一切都完成后,我发回一个 NSArray,其中包含一个实时游戏列表。

在测试通过块传递 NSArray 的解析方法时,我在 SenTestCase 中发现了一个奇怪的行为。在我的测试中,我可以执行 [myArray count] 并在 NSLog 中显示它的结果,但是当我执行 STAssertEquals([myArray count], 1, @"Error description")时,测试会出现 EXC_BAD_ACCESS 崩溃。

这是我的代码减少到最低限度,并且我删除了所有网络方面:

#import <SenTestingKit/SenTestingKit.h>


@interface LiveGameTests : SenTestCase
@end

@interface LiveGame : NSObject
@property (nonatomic) id gameID;
@property (strong, nonatomic) NSString *arenaName;
@end

@implementation LiveGame

// Create a live game object from a dictionary (this dictionary is the response of a first request to a remote server)
+(LiveGame *)gameWithData:(NSDictionary *)dict
{
    LiveGame *liveGame = [[LiveGame alloc] init];
    liveGame.gameID = dict[@"game_id"];    
    return liveGame;
}

// Complete a live game data with the element of a dictionary (those data are actualy fetched from a remote server in a different request.)
+(void)fetchRemainingData:(NSArray *)liveGameList completion:(void(^)(void))completion
{
    LiveGame *liveGame = liveGameList[0];
    liveGame.arenaName = @"arenaName";
    completion();
}

// Parse a NSArray of NSDictionaries representing live game
+(void)parseArrayOfDictionary:(NSArray *)arrayToParse success:(void(^)(NSArray *liveGameList))success
{
    NSMutableArray *liveGameList = [NSMutableArray arrayWithCapacity:[arrayToParse count]];

    // Iterate on all the NSDictionary of the NSArray and create live game from each NSDictionary 
    [arrayToParse enumerateObjectsUsingBlock:^(NSDictionary *obj, NSUInteger idx, BOOL *stop)
     {
         liveGameList[idx] = [LiveGame gameWithData:obj];
     }];

    [LiveGame fetchRemainingData:liveGameList completion:^
     {
         success(liveGameList);
     }];
}
@end

@implementation LiveGameTests

-(void)testParseArrayOfDictionary
{
    [LiveGame parseArrayOfDictionary: @[@{@"game_id": @1}]
        success:^(NSArray *liveGameList)
        {
            // This line work fine and print: 2013-03-08 13:39:35.288 ShotClock[55177:c07] liveGameList count = 1
            NSLog(@"liveGameList count = %d",[liveGameList count]);

            // This crash the test on a EXC_BAD_ACCESS. What's wrong?
            STAssertEquals([liveGameList count], 1, @"The list of game must contain one unique live game but contain %@",[liveGameList count]);
        }];
}
@end

NSLog(@"liveGameList count = %d",[liveGameList count]); => 这行工作正常并打印:2013-03-08 13:39:35.288 ShotClock[55177:c07] liveGameList count = 1

STAssertEquals([liveGameList count], 1, @"游戏列表必须包含一个唯一的现场游戏,但包含%@",[liveGameList count]); => 这会使 EXC_BAD_ACCESS 上的测试崩溃。怎么了?

【问题讨论】:

    标签: ios objective-c nsarray objective-c-blocks


    【解决方案1】:

    您的应用程序崩溃了,因为

      STAssertEquals([liveGameList count], 1,  @"The list of game must contain one unique live game but contain %@",[liveGameList count])
    

    尝试将 %@ 格式化程序应用于 [liveGameList count] 的结果。但是 %@ 需要一个 Objective C 对象,其中 [liveGameList count] 返回标量“1”。运行时将该标量转换为指向 0x00000001 的指针,并尝试使用它在那里找到的“对象”。但这不是一个有效的指针,因此运行时会引发无效地址异常。

    【讨论】:

    • 感谢您的快速回答。这很明显,但我完全专注于 NSArray 和 Block,因为我之前遇到了一个错误。
    • 非常自然!很容易忘记您的诊断可能是导致崩溃的原因!
    【解决方案2】:

    我认为 STAssertEquals 需要 2 个对象,你应该这样做

    STAssertTrue([myArray count] == expectedCount, @"Count is wrong);
    

    【讨论】:

    • 非常感谢。这有效地工作。您让我想到的另一个解决方案是将 1 替换为 1U:STAssertEquals([liveGameList count], 1U, @"The list of game must contain one unique live game but contain %@",[liveGameList count]); 我知道测试是否失败但它会崩溃。有人给我解释一下吗?谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-08
    • 1970-01-01
    • 2023-03-29
    • 2011-01-20
    • 1970-01-01
    相关资源
    最近更新 更多