0

HeroState という名前のクラスがあります。これは CharacterProperties という名前の別のクラスから継承したもので、armorId、headId、earsId、およびキャラクターを作成するためのその他の一般的な値が含まれています。この新しいクラスでは、ヘッダーで宣言しました。(シングルトンといってもプレイヤーの進行を担当するクラスです)

    @interface HeroState : CharacterProperties <NSCoding>  {
    ControlsType controlsType;
    characterJob charJob;
    MonsterJob monsterJob;
    } 


@property MonsterJob monsterJob;
@property characterJob charJob;
@property (readwrite)ControlsType controlsType;

+ (HeroState *) sharedInstance;
- (void)save;

@end

そして、クラスの保存とロードを担当する「データベース」クラスがあります。

データベースヘッダー:

#import <Foundation/Foundation.h>

id loadData(NSString * filename);
void saveData(id theData, NSString *filename);

データベースの実装:

NSString * pathForFile(NSString *filename) {
    // 1
    NSArray *paths =
    NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
                                        NSUserDomainMask,
                                        YES);
    // 2
    NSString *documentsDirectory = [paths objectAtIndex:0];
    // 3
    return [documentsDirectory
            stringByAppendingPathComponent:filename];
}

id loadData(NSString * filename) {
    // 4
    NSString *filePath = pathForFile(filename);
    // 5
    if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
        // 6
        NSData *data = [[[NSData alloc]
                         initWithContentsOfFile:filePath] autorelease];
        // 7
        NSKeyedUnarchiver *unarchiver = [[[NSKeyedUnarchiver alloc]
                                          initForReadingWithData:data] autorelease];
        // 8
        id retval = [unarchiver decodeObjectForKey:@"Data"];
        [unarchiver finishDecoding];
        return retval;
    }
    return nil;
}

void saveData(id theData, NSString *filename) {
    // 9
    NSMutableData *data = [[[NSMutableData alloc] init] autorelease];
    // 10
    NSKeyedArchiver *archiver = [[[NSKeyedArchiver alloc]
                                  initForWritingWithMutableData:data] autorelease];
    // 11
    [archiver encodeObject:theData forKey:@"Data"];
    [archiver finishEncoding];
    // 12
    [data writeToFile:pathForFile(filename) atomically:YES];
}

しかし、それを HeroClass で使用すると

+(HeroState*)sharedInstance {
    @synchronized([HeroState class])
    {
        if(!sharedInstance) {
            sharedInstance = [loadData(@"HeroState") retain];
            if (!sharedInstance) {
                [[self alloc] initWithNewStats];
            }
        }
        return sharedInstance;
    }
    return nil;
}

そして、保存するためにここに

- (void)save {
    saveData(self, @"HeroState");
}

ビルドしようとするとエラーが発生します。

アーキテクチャ i386 の未定義シンボル: "loadData(NSString*)"、参照元: +[HeroState sharedInstance] in HeroState.o "saveData(objc_object*, NSString*)"、参照元: -[HeroState save] in HeroState.o ld : アーキテクチャ i386 clang のシンボルが見つかりません: エラー: リンカー コマンドが終了コード 1 で失敗しました (呼び出しを確認するには -v を使用してください)

NSCoding のプロトコルに固執する initWithCoder 関数と encodeWithCoder 関数があります。では、何が間違っているのでしょうか?以前はこのクラスを NSObject 継承クラスとして使用していましたが、問題はありませんでしたが、CharacterProperties クラスの継承として再作成することにしたときに、NSObject の継承である問題が発生しました。

どんな種類の助けにも感謝します!

4

1 に答える 1

0

これらを C 関数として宣言したかったのは確かですか?

NSString * pathForFile(NSString *filename) {..}
id loadData(NSString * filename) {..}
void saveData(id theData, NSString *filename)  {..}

おそらく、それらを静的クラス関数として宣言する必要があります。

+(id) loadData:(NSString *)filename {..}
// similar for the other C functions

それに応じて呼び出します:

sharedInstance = [[HeroState loadData:@"HeroState"] retain];

PS: ARC の使用を開始してください。今の時代、やらない理由はありません。

于 2013-10-26T18:25:53.090 に答える