I have these 2 classes inside the following files:
SFSelector.h
SFSelector.m
The problem is that I want to save/load data from those classes to a file. I will need to transform the classes to NSData first. However, this is a test code I have written to test wether the encoding and decoding is done correctly.
The above code does not work. After conversion to NSData, unarchiving will result in an empty class. However, if I do the initializations to the ModSelector's -init method (put 2 ModStatus objects inside the class) and then encode it using NSKeyedArchiver and decode it with NSKeyedUnarchiver, it will work correctly. Can anyone tell my why this happens?
SFSelector.h
Code:
#import <Cocoa/Cocoa.h>
@interface ModStatus: NSObject <NSCoding>{
NSMutableDictionary *properties;
}
- (void)setProperties:(NSDictionary *)otherProperties;
- (NSMutableDictionary *)properties;
@end
#pragma mark -
enum selectedMod {FIRST_MOD=0, SECOND_MOD=1, THIRD_MOD=2};
@interface ModSelector : NSObject <NSCoding>{
NSMutableArray *modStatuses;
int SELECTED_MOD;
}
- (id) initWithStatuses :(NSArray *)statuses;
- (void)changeSelectedMod:(int)newSelection;
- (void)setModStatuses:(NSArray *)newModStatuses;
- (void)addModStatus:(ModStatus *)modStatus;
- (void)removeModStatusAtIndex:(unsigned)index;
- (ModStatus *)currentModStatus;
- (ModStatus *)modStatusAtIndex:(unsigned)index;
- (NSMutableArray *)modStatuses;
- (unsigned)count;
- (void)selectModWithName:(NSString *)name;
- (void)setModSelector:(ModSelector *)aSelector;
- (id)valueForCurrentModKey: (id)key;
@end
SFSelector.m
Code:
#pragma mark -
#pragma mark ModStatus
#import "SFSelector.h"
@implementation ModStatus
#pragma mark Inits, setters, getters
- (id) init
{
self = [super init];
if (self != nil) {
NSArray *values = [NSArray arrayWithObjects:@"modName", @"modLocation", @"preferenceFileLocation", @"isFirstTime",nil];
NSArray *keys = [NSArray arrayWithObjects:@"<not set>", @"<mod location not set>", @"<not set>", [NSNumber numberWithBool:YES], nil];
properties = [NSMutableDictionary dictionaryWithObjects:values forKeys:keys];
}
return self;
}
- (void)setProperties:(NSDictionary *)otherProperties
{
[properties setDictionary:otherProperties];
}
- (NSMutableDictionary *)properties
{
return properties;
}
#pragma mark NSCoding
- (void)encodeWithCoder:(NSCoder *)coder
{
[coder encodeObject:properties forKey:@"properties"];
}
- (id)initWithCoder: (NSCoder *) coder
{
properties = [[coder decodeObjectForKey:@"properties"]retain];
return self;
}
#pragma mark dealloc
- (void) dealloc
{
[properties release];
[super dealloc];
}
@end
//________________________________________________________
#pragma mark -
#pragma mark ModSelector
#pragma mark Inits, setters, getters
@implementation ModSelector
- (id) init
{
self = [super init];
if (self != nil) {
modStatuses = [[NSMutableArray alloc]init];
SELECTED_MOD = FIRST_MOD;
}
return self;
}
- (id) initWithStatuses :(NSArray *)statuses
{
self = [super init];
if (self != nil) {
modStatuses = [[NSMutableArray alloc]init];
[modStatuses setArray:statuses];
}
return self;
}
- (void)setModStatuses:(NSArray *)newModStatuses
{
[modStatuses setArray:newModStatuses];
}
- (void)addModStatus:(ModStatus *)modStatus
{
[modStatuses addObject:modStatus];
NSLog(@"%i",[modStatuses count]);
}
- (void)removeModStatusAtIndex:(unsigned)index
{
[modStatuses removeObjectAtIndex:index];
}
- (ModStatus *)currentModStatus
{
return [modStatuses objectAtIndex:SELECTED_MOD];
}
-(void)selectModWithName:(NSString *)name
{
int i;
for (i=0; i<[modStatuses count]; i++) {
//NSLog(@"ASD");
if ([name isEqualToString:[[[modStatuses objectAtIndex:i]properties]valueForKey:@"modName"]] == TRUE){
SELECTED_MOD = i;
break;
}
}
}
- (NSMutableArray *)modStatuses
{
return modStatuses;
}
- (ModStatus *)modStatusAtIndex:(unsigned)index
{
if ([self count] > index)
return [modStatuses objectAtIndex:index];
return nil;
}
- (void)changeSelectedMod:(int)newSelection
{
SELECTED_MOD = newSelection;
}
- (void)setModSelector:(ModSelector *)aSelector
{
[modStatuses setArray:[aSelector modStatuses]];
SELECTED_MOD = 0;
}
#pragma mark Getting mod parameters
- (id)valueForCurrentModKey: (id)key
{
ModStatus *currentObject = [modStatuses objectAtIndex:SELECTED_MOD];
return [[currentObject properties]valueForKey:key];
}
- (unsigned)count
{
return [modStatuses count];
}
#pragma mark NSCoding
- (void)encodeWithCoder:(NSCoder *)coder
{
[coder encodeObject:modStatuses forKey:@"modStatuses"];
}
- (id)initWithCoder: (NSCoder *) coder
{
if (modStatuses != nil)
[modStatuses release];
modStatuses = [[coder decodeObjectForKey:@"modStatuses"]retain];
return self;
}
#pragma mark dealloc
- (void) dealloc
{
[modStatuses release];
[super dealloc];
}
@end
The problem is that I want to save/load data from those classes to a file. I will need to transform the classes to NSData first. However, this is a test code I have written to test wether the encoding and decoding is done correctly.
Code:
ModSelector *defaultModSelector = [[ModSelector alloc]init];
ModStatus *status1 = [[ModStatus alloc]init];
ModStatus *status2 = [[ModStatus alloc]init];
[[status1 properties]setValue:@"FS2_Open" forKey:@"modName"];
[[status2 properties]setValue:@"Beyond The Red Line" forKey:@"modName"];
[mainModSelector addModStatus:status1];
[mainModSelector addModStatus:status2];
NSData *defaultModStatusData = [NSKeyedArchiver archivedDataWithRootObject:defaultModSelector];
ModSelector *temp = [NSKeyedUnarchiver unarchiveObjectWithData:defaultModStatusData];
NSLog(@"%i, %@",[temp count], [[[temp modStatusAtIndex:0]properties]valueForKey:@"modName"]);
The above code does not work. After conversion to NSData, unarchiving will result in an empty class. However, if I do the initializations to the ModSelector's -init method (put 2 ModStatus objects inside the class) and then encode it using NSKeyedArchiver and decode it with NSKeyedUnarchiver, it will work correctly. Can anyone tell my why this happens?