2

私はスポーツの現在のライブ ゲームを一覧表示するアプリケーションに取り組んでいます。ライブ ゲームに関する情報は、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 カウント = %d",[liveGameList カウント]); => この行は正常に動作し、印刷されます: 2013-03-08 13:39:35.288 ShotClock[55177:c07] liveGameList count = 1

STAssertEquals([liveGameList count], 1, @"ゲームのリストには、1 つの一意のライブ ゲームが含まれている必要がありますが、%@ が含まれている必要があります",[liveGameList count]); => これにより、EXC_BAD_ACCESS でテストがクラッシュします。どうしたの?

4

2 に答える 2

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 へのポインタに変換し、そこで見つけた「オブジェクト」を使用しようとします。しかし、これは有効なポインターではないため、ランタイムは無効なアドレス例外を発生させます。

于 2013-03-08T13:19:39.777 に答える
0

STAssertEquals は 2 つのオブジェクトを想定していると思います。次のようにする必要があります。

STAssertTrue([myArray count] == expectedCount, @"Count is wrong);
于 2013-03-08T13:02:01.543 に答える