2016-05-28 1 views
0

私は数日間追跡しようとしている非常に奇妙なバグがあります。私はゲームの状態データを、アプリケーションのDocumentsディレクトリにあるファイルに保存しています。NSKeyedArchiver TestFlight経由でiTunesからアプリケーションをダウンロードしたときの問題

最新のiOSアップデート(すべてのバージョンは9.0、どこか正確にはわからない)まで、すべてが正常に機能していました。突然、データが正しくアーカイブ/アーカイブ解除されていません。

奇妙な部分は、私のMACに縛られたiPadまたはエミュレータの中で、Xcodeから実行するとコードがうまく動作します。 TestFlightを使ってiTunesからアプリをダウンロードすると、もう機能しません。これにより、デバッグが非常に困難になりました。

すべてをチェックした後、URLパスを使用したり、エラートラップコードを追加したりしていますが、TestFlight経由でiTunesからアプリケーションをインストールするとアーカイブが正常に動作しません。

最後の手段として、オブジェクトをアーカイブする新しいコードを追加し、直ちに別の変数に保存してから、ラベルにデータを表示します。結果のオブジェクトにはヌルデータが含まれます。

例外はスローされません。

ちょっとだけ言い換えれば、iTunesからインストールされたアプリの場合のみ、コードは機能しません。

ここにコードスニペットがあります。ここで

NSString *documentDirectory = [[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject] path]; 
    NSString* filePath = [documentDirectory stringByAppendingPathComponent:@"playerTest.data"]; 
    LBYPlayerData* pd1 = [[LBYPlayerData alloc ]init]; 
    pd1.currentCountryID = 1; 
    pd1.lsn = @"123.456"; 
    BOOL success = [NSKeyedArchiver archiveRootObject:pd1 toFile:filePath]; 
    NSAssert(success, @"archiveRootObject failed"); 
    LBYPlayerData* pd2 = nil; 
    @try { 
     pd2 = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath]; 
    } @catch (NSException *exception) { 
     playerDataLabel.text = [NSString stringWithFormat:@"%@",exception.name]; 
     playerUndoDataLabel.text = [NSString stringWithFormat:@"%@",exception.description]; 
    } @finally { 
     NSAssert((pd2 != nil), @"archivePlayerDataUndo failed to unarchive"); 
     playerDataLabel.text = [NSString stringWithFormat:@"path: %@",filePath]; 
     playerUndoDataLabel.text = [NSString stringWithFormat:@"Undo Country:%li LSN:%@",(long)pd2.currentCountryID,pd2.lsn]; 
    } 

// 
// LBYPlayerData.h 

#import <Foundation/Foundation.h> 

@interface LBYPlayerData : NSObject 

@property (nonatomic,readonly) BOOL isNewGame; 
@property (nonatomic) NSInteger playerID; 
@property (nonatomic) NSInteger usCardIdx; 
@property (nonatomic) NSInteger drawDeckIdx; 
@property (nonatomic) NSInteger discardDeckIdx; 
@property (nonatomic) NSInteger removeDeckIdx; 
@property (nonatomic) NSInteger currentCountryID; 
@property (nonatomic) NSString* lsn; 
@property (nonatomic) NSString* build; 

@end 

// 
// LBYPlayerData.m 

#import "LBYPlayerData.h" 

@implementation LBYPlayerData 

-(id)init 
{ 
    self = [super init]; 
    _isNewGame = YES; 
    return self; 
} 

-(void)encodeWithCoder:(NSCoder *)aCoder 

{ 
// NSLog(@"Saving Player Data"); 
    _isNewGame = NO; 
    [aCoder encodeBool:_isNewGame   forKey: NSStringFromSelector(@selector(isNewGame))]; 
    [aCoder encodeInt64:_playerID   forKey: NSStringFromSelector(@selector(playerID))]; 
    [aCoder encodeInt64:_usCardIdx  forKey: NSStringFromSelector(@selector(usCardIdx))]; 
    [aCoder encodeInt64:_drawDeckIdx  forKey: NSStringFromSelector(@selector(drawDeckIdx))]; 
    [aCoder encodeInt64:_discardDeckIdx forKey: NSStringFromSelector(@selector(discardDeckIdx))]; 
    [aCoder encodeInt64:_removeDeckIdx forKey: NSStringFromSelector(@selector(removeDeckIdx))]; 
    [aCoder encodeInt64:_currentCountryID forKey: NSStringFromSelector(@selector(currentCountryID))]; 
    [aCoder encodeObject:_lsn    forKey: NSStringFromSelector(@selector(lsn))]; 
    [aCoder encodeObject:_build   forKey: NSStringFromSelector(@selector(build))]; 
// NSLog(@"Current Counry: %li",(long)_currentCountryID); 
} 

-(id)initWithCoder:(NSCoder *)aDecoder 
{ 
// NSLog(@"Loading Player Data"); 
    self = [self init]; 
    if (self) { 
     _isNewGame    =[aDecoder decodeBoolForKey:NSStringFromSelector(@selector(isNewGame))]; 
     [self setPlayerID  :[aDecoder decodeIntegerForKey:NSStringFromSelector(@selector(playerID))]]; 
     [self setUsCardIdx  :[aDecoder decodeIntegerForKey:NSStringFromSelector(@selector(usCardIdx))]]; 
     [self setDrawDeckIdx  :[aDecoder decodeIntegerForKey:NSStringFromSelector(@selector(drawDeckIdx))]]; 
     [self setDiscardDeckIdx :[aDecoder decodeIntegerForKey:NSStringFromSelector(@selector(discardDeckIdx))]]; 
     [self setRemoveDeckIdx :[aDecoder decodeIntegerForKey:NSStringFromSelector(@selector(removeDeckIdx))]]; 
     [self setCurrentCountryID:[aDecoder decodeIntegerForKey:NSStringFromSelector(@selector(currentCountryID))]]; 
     [self setLsn    :[aDecoder decodeObjectForKey :NSStringFromSelector(@selector(lsn))]]; 
     [self setBuild   :[aDecoder decodeObjectForKey :NSStringFromSelector(@selector(build))]]; 
    } 
    return self; 
} 

@end 
+0

リリースビルドで 'NSAssert'が無効になり、ラベルに割り当てられたNSExceptionの説明は常に' @ finally'ステートメントで上書きされます。だから、あなたはその問題に関する情報を見ることができない、と私は考えている。 – mmtootmm

+0

NSAssertが問題のようです。 NSAssertステートメント内でファイルをアーカイブした関数を呼び出すコードをいくつか見つけました。ありがとう。これは私を夢中にさせている。 – JVC

答えて

0

問題がNSAssertとしたデータモデルです。 NSAssertステートメント内でオブジェクトをアーカイブする関数を呼び出すコードが見つかりました。

関連する問題