1

I am trying to archive an NSObject that I send through match data in a game center turn based game.

Below is my code for archiving my object

turnDataObject MyData = [[turnDataObject alloc] init];

data = [NSKeyedArchiver archivedDataWithRootObject:MyData];

This is my code for unarchiving my object

readMyData = [NSKeyedUnarchiver unarchiveObjectWithData:data] ;

However when I run this code I get an error

 thread 1 exc bad access code

I think that this might have to do with sending addresses when I archive data. How do I send something that will be readable when I unarchive it?

Edit 1: I get the error on the next line after I unarchive. it says that the adress I am trying to access is null. I remember reading somewhere that I souldn't send adresses of my NSObject but I am not sure how to convert it to something else.

readMyData = [NSKeyedUnarchiver unarchiveObjectWithData:data] ;

NSLog(@"current game happens to be: %@", readMyData.currentGame);

Edit 2: here is my init with coder and encode with coder

 - (instancetype)initWithCoder:(NSCoder *)decoder
 {
     self = [self init];
     if (self) {

         _currentGame = [decoder decodeObjectForKey:currentGameDataKey];

    }
    return self;
 } 

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

    //scores data keys
    [encoder encodeObject:self.currentGame forKey:currentGameDataKey];

 }

Edit 3: _currentGame is in my objects .h file

 @property (assign, nonatomic) NSString *currentGame;
Sooc
  • 141
  • 7
  • 1
    You need to provide more details. Which line of code actually causes the crash? Show more of the stack trace. Show more of the relevant code. – rmaddy Aug 21 '15 at 16:30
  • Again, show relevant code to the issue. Start with your `initWithCoder:` method. – rmaddy Aug 21 '15 at 16:40
  • What is `_currentGame`? Is there `initWithCoder:` and `encodeWithCoder:` methods for that? – rmaddy Aug 21 '15 at 16:51
  • Since you are calling `[self init]` in your `initWithCoder:` method, also post your `init` method. – rmaddy Aug 21 '15 at 17:05
  • If you added NSCoding protocol into your class declaration, you don't need to add `[self init]` or `[super init]` into your `initWithCoder` implementation. – deoKasuhal Aug 21 '15 at 17:12
  • @deoKaushal This is not true. all `initXXX` methods must call (ultimately) `super init`. – rmaddy Aug 21 '15 at 18:11

3 Answers3

0

I would suggest creating NSKeyedArchiver and NSKeyedUnarchiver objects and using those instead of using the type (which it looks like you're doing.)

I usually program in Swift but here's a shot at example code:

theArchiver NSKeyedArchiver = [[theArchiver alloc] init];
data = [theArchiver archivedDataWithRootObject:MyData];

Then you would do the same thing with the NSKeyedUnarchiver.

  • Where did you pull `readMyData = [NSKeyedUnarchiver unarchiveObjectWithData:data] ; NSLog(@"current game happens to be: %@", readMyData.currentGame);` out of your code? – miniluigi008 Aug 21 '15 at 16:53
0

Your initWithCoder implementation is wrong:

 self = [self init];

That should be:

 self = [super init];
matt
  • 515,959
  • 87
  • 875
  • 1,141
  • Not necessarily. Depending on how things are coded, calling `[self init[` from another `initXXX` method can be correct. – rmaddy Aug 21 '15 at 17:02
  • 1
    He _must_ call `super` one way or another. I am assuming that he is failing to do this. – matt Aug 21 '15 at 17:03
  • Agreed. Let's see what what the `init` method does once the OP posts it. – rmaddy Aug 21 '15 at 17:06
-1

You need to add NSCoding protocol to MyData Class, here is the code snippet with supporting NSCoding in order to add Archiving support to NSObjet.

MyData.h

@interface MyData : NSObject <NSCoding>
@property (nonatomic, strong) NSString *currentGame;
@end

MyData.m

//This method is optional, if you need constructor for current game 
- (instancetype)initWithCurrentGame:(NSDictionary *)currentGame {
    self = [super init];
    if (self) {
        self.currentGame = currentGame;
    }
    return self;
}


-(void)encodeWithCoder:(NSCoder *)encoder {
    [encoder encodeObject:self.currentGame forKey:@"currentGame"];
}

-(id)initWithCoder:(NSCoder *)decoder {
    self.currentGame = [decoder decodeObjectForKey:@"currentGame"];
    return self;
}
deoKasuhal
  • 2,867
  • 20
  • 27
  • This is obviously already in place. If it wasn't, the code wouldn't even compile. And even it would compile without specifying the `NSCoding` protocol, the methods are implemented as posted in the question. The possible lack of the protocol would not result in the runtime exception mentioned in the question. – rmaddy Aug 21 '15 at 17:17