Вы, конечно, можете сохранять свои собственные объекты, используя класс NSKeyedArchiver
, как хотите.
Но:
- (id)initWithCoder:(NSCoder *)decoder
{
//self = [[Freeze alloc] init]; // I don't think you want to
// allocate a new object here,
self = [super init];
if( self != nil )
{
//decode properties, other class vars
self.name = [decoder decodeObjectForKey:@"name"];
}
return self;
}
И, как упоминалось ранее, вы не можете сохранить его в NSUserDefaults.
Вы можете сохранить его в файл в каталоге документов приложения.
РЕДАКТИРОВАТЬ: вот код, который я написал около года назад в качестве теста. Я думаю, это может быть очень близко к тому, что вы пытаетесь сделать. Там есть кое-что, что не связано, например, загрузка plist из основного пакета, но я оставлю это на всякий случай, если кто-то найдет это полезным.
HighScoresManager.h
#import <Foundation/Foundation.h>
@interface ScoreEntry : NSObject <NSCoding>
{
NSString *player;
NSInteger score;
}
@property (nonatomic, retain) NSString *player;
@property (nonatomic, assign) NSInteger score;
+ (ScoreEntry *) entryWithScore:(NSInteger) score andPlayer:(NSString *)player;
@end
@interface HighScoresManager : NSObject
{
NSMutableArray *m_Highscores;
}
@property (nonatomic, readonly) NSArray *highscores;
- (void) addScore: (NSInteger) score forPlayer:(NSString *)player;
- (void) addScoreEntry: (ScoreEntry *) entry;
@end
HighScoresManager.m
#import "HighScoresManager.h"
@implementation ScoreEntry
@synthesize player;
@synthesize score;
+ (ScoreEntry *) entryWithScore:(NSInteger) score andPlayer:(NSString *)player
{
ScoreEntry *entry = [[[ScoreEntry alloc] init] autorelease];
entry.score = score;
entry.player = player;
return entry;
}
+ (ScoreEntry *) entryWithNSDictionary:(NSDictionary *)dict
{
ScoreEntry *entry = [[[ScoreEntry alloc] init] autorelease];
entry.score = [[dict objectForKey:@"score"] intValue];
entry.player = [dict objectForKey:@"player"];
return entry;
}
- (void) encodeWithCoder: (NSCoder *) coder
{
[coder encodeInteger:score forKey:@"score"];
[coder encodeObject:player forKey:@"player"];
}
- (id) initWithCoder: (NSCoder *) decoder
{
if( self = [super init] )
{
score = [decoder decodeIntForKey:@"score"];
player = [[decoder decodeObjectForKey:@"player"] retain];
}
return (self);
}
- (void) dealloc
{
[player release];
[super dealloc];
}
@end
@implementation HighScoresManager
- (BOOL) saveHighScores
{
BOOL success = NO;
if( m_Highscores )
{
NSArray *pathList = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, NO);
NSString *path = [[[pathList objectAtIndex:0] stringByAppendingPathComponent:@"highscores.txt"] stringByExpandingTildeInPath];
success = [NSKeyedArchiver archiveRootObject:m_Highscores toFile:path];
}
return success;
}
- (BOOL) loadHighScores
{
BOOL success = NO;
NSArray *pathList = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, NO);
NSString *path = [[[pathList objectAtIndex:0] stringByAppendingPathComponent:@"highscores.txt"] stringByExpandingTildeInPath];
if(m_Highscores)
{
[m_Highscores release];
}
m_Highscores = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
if( m_Highscores )
{
[m_Highscores retain];
success = YES;
}
else
{
m_Highscores = [[NSMutableArray alloc] init];
success = NO;
}
// if empty, load default highscores from plist
if([m_Highscores count] == 0)
{
NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
NSString *path = [[resourcePath stringByAppendingPathComponent:@"DefaultHighscores.plist"] stringByExpandingTildeInPath];
NSDictionary *defaultHighscoresDict = [[NSDictionary alloc] initWithContentsOfFile:path];
NSArray *defaultHighscores = [defaultHighscoresDict objectForKey:@"highscores"];
for (NSDictionary *dict in defaultHighscores)
{
[m_Highscores addObject:[ScoreEntry entryWithNSDictionary:dict]];
}
[defaultHighscoresDict release];
}
return success;
}
- (id) init
{
self = [super init];
if(self)
{
[self loadHighScores];
}
return self;
}
- (NSArray *) highscores
{
return (NSArray *) m_Highscores;
}
- (void) addScore: (NSInteger) score forPlayer:(NSString *)player
{
[self addScoreEntry:[ScoreEntry entryWithScore:score andPlayer:player]];
}
- (void) addScoreEntry: (ScoreEntry *) entry
{
[m_Highscores addObject:entry];
}
- (void) dealloc
{
[self saveHighScores];
[m_Highscores release];
[super dealloc];
}
@end
Может быть, я должен был просто загрузить файлы куда-нибудь и связать их здесь ... в любом случае, это сделано сейчас.