2013-03-08 23 views
1

我工作的應用程序列出了一項運動的當前現場比賽。有關實時遊戲的信息是使用REST從遠程源獲取的。第一個請求給出了他們的id和相應的競技場ID的現場比賽列表。然後,我必須從他們的身份證獲取競技場名稱。當所有完成後,我發回一個NSArray包含一個現場比賽列表。Objective-C NSArray,Block,STAssertEquals

在測試我的解析方法傳遞NSArray通過塊時,我在SenTestCase中發現了一個奇怪的方法。在我的測試中,我能夠執行[myArray count]並將結果顯示在NSLog中,但是當我使用EXC_BAD_ACCESS執行STAssertEquals([myArray count], 1, @"Error description")測試崩潰時。

這是我的代碼減少到最低限度,並且其中我刪除所有的網絡方面:

#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,@「遊戲列表必須包含一個獨特的現場比賽,但包含%@「,[liveGameList計數]); =>這會使EXC_BAD_ACCESS上的測試崩潰。怎麼了?

回答

1

你的應用程序崩潰,因爲

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

嘗試將%@格式適用於[liveGameList數]的結果。但%@期望一個Objective C對象,其中[liveGameList count]返回標量「1」。運行時將標量轉換爲指向0x00000001的指針,並嘗試使用它在其中找到的「對象」。但這不是一個有效的指針,所以運行時會引發無效的地址異常。

+0

感謝您的快速回答。這很明顯,但我完全專注於NSArray和Block,因爲之前的錯誤。 – JonathanGailliez 2013-03-08 13:26:23

+0

非常自然!很容易忘記你的診斷可能是導致崩潰的原因! – 2013-03-08 13:35:46

0

我覺得STAssertEquals預計2個對象,你應該這樣做

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

非常感謝。這有效地工作。另一個你讓我想到的解決方案是用1U代替1: 'STAssertEquals([liveGameList count],1U,@「遊戲列表必須包含一個獨特的現場遊戲,但包含%@」,[liveGameList count]); ' 我明白如果測試失敗,但它會崩潰。有人有我的解釋嗎? 謝謝。 – JonathanGailliez 2013-03-08 13:07:12