سؤال

Hi, I am trying to save an object from a class I have created. It is called shot and Contains 5 variables I wish to save. Here is the .h file--- It cut off NSCoding and NSMutableCopying Protocals and my imports, but they are there.

#import <Foundation/Foundation.h>


@interface Shot : UIButton <NSCoding, NSMutableCopying> {

 int x;
 int y;
 int location;
 int quarter;
 bool made;

 int miss;
 int make;
}

@property()int x;

@property()int y;

@property()int location;

@property()int quarter;

@property()bool made;

-(void)set_x:(int)my_x set_y:(int)my_y set_quarter:(int)my_quarter set_made:(bool)my_made set_location:(int)my_location;

-(void)set_miss_AND_set_make;

@end

**Here are the methods I made to save the data in my .m file---**

-(void)encodeWithCoder:(NSCoder *)aCoder {

 [aCoder encodeInt:x forKey:@"x"];
 [aCoder encodeInt:y forKey:@"y"];
 [aCoder encodeInt:location forKey:@"location"];
 [aCoder encodeInt:quarter forKey:@"quarter"];
 [aCoder encodeBool:made forKey:@"made"];
}

-(id)initWithCoder:(NSCoder *)aDecoder {

 if (self = [super init]) {
 x = [aDecoder decodeIntForKey:@"x"];
 y = [aDecoder decodeIntForKey:@"y"];
 location = [aDecoder decodeIntForKey:@"location"];
 quarter = [aDecoder decodeIntForKey:@"quarter"];
 made = [aDecoder decodeBoolForKey:@"made"];
 }
 return self;
}

-(id)mutableCopyWithZone:(NSZone *)zone {

 Shot *newShot = [[Shot allocWithZone:zone]init];
 [newShot set_x:x set_y:y set_quarter:quarter set_made:made set_location:location];
 return newShot;
}

I can't seem to get my data to saved when I use these methods

-(NSString *)getPath {

 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
 NSString *documentFolder = [paths objectAtIndex:0];
 NSFileManager *fm = [[NSFileManager alloc]init];
 if ([fm fileExistsAtPath:documentFolder] == NO) {
  [fm createDirectoryAtPath:documentFolder withIntermediateDirectories:YES attributes:nil error:nil];
 }
 return [documentFolder stringByAppendingFormat:@"iStatTrackInfo.archive"];
}

-(void)saveData {

 NSString *path = [self getPath];
 [NSKeyedArchiver archiveRootObject:shotArray toFile:path];
}

-(void)loadData {

 NSString *path = [self getPath];
 NSFileManager *fm = [[NSFileManager alloc]init];
 if ([fm fileExistsAtPath:path] == YES) {
  shotArray = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
  return;
 }

 NSEnumerator *enumOne = [shotArray objectEnumerator];
 Shot *shotObject = [[Shot alloc]init];
 while (shotObject = [enumOne nextObject]) {
  Shot *shotShot = [[Shot alloc]init];
  shotShot = [shotObject mutableCopy];
  shotShot.frame = CGRectMake(0, 0, 50, 50);
  shotShot.backgroundColor = [UIColor whiteColor];
  [self addSubview:shotShot];
 }
}

I have set the save and load methods up to buttons, but my data still won't save. Please help!!!

هل كانت مفيدة؟

المحلول

I have finally solved the problem. Other than the above help, .archive isn't a file type. You can't save a .archive, you can only save a .arch or a .plist That was my main problem.

نصائح أخرى

First, you are leaking memory like a sieve. Lots of alloc/init & mutableCopy, no releases. I'd suggest reading the memory management guide.

Next, your method names are not following the Cocoa conventions. These:

-(void)set_x:(int)my_x set_y:(int)my_y set_quarter:(int)my_quarter set_made:(bool)my_made set_location:(int)my_location;

-(void)set_miss_AND_set_make;

Should be something like:

-(void) resetMissAndMake; // or just missAndMake or activateMissAndMake
-(void) setX:(NSInteger)xValue y:(NSInteger)yValue quarter:(NSInteger)quarterValue location:(NSInteger)aLocation;

Also, getPath should just be path. Methods prefixed with get are both very rare and have a very specific meaning.

This is also nonsense:

 Shot *shotObject = [[Shot alloc]init];
 while (shotObject = [enumOne nextObject]) {
  Shot *shotShot = [[Shot alloc]init];
  shotShot = [shotObject mutableCopy];

There is no need for either of the [[Shot alloc]init] calls (those are both leaks).

Finally, your encoding methods are implemented incorrectly. As the documentation states, you need to call super as appropriate.

Specifically, your encodeWithCoder: must invoke super's implementation of same and initWithCoder: should call super's initWithCoder:, not init.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top