开发者

Can't set member variable twice (NSManagedObject)

开发者 https://www.devze.com 2023-03-09 16:28 出处:网络
I am getting the EXC_BAD_ACCESS error when trying to set a value inside a subclass of NSManagedObject for the second time.

I am getting the EXC_BAD_ACCESS error when trying to set a value inside a subclass of NSManagedObject for the second time.

I am using zombies but nothing is showing up in the console. Printing out the object using GDB I see that the object has the same memory address both times I try to set the value - not sure why though.

Situation:

  1. I have a view (A) that, when a QR code is scanned, adds a subview (B) which in turn downloads XML that is then saved into a subclassed NSManagedObject.
  2. Inside the subview (B) I navigate back (removeFromSuperView is called)
  3. Back in the original view (A)
  4. Next time, when the same QR code is scanned, it (A) finds the NSManagedObject from the database and attaches that to an instance variable on a new view (same type as B) that it then adds as a subview to the original (A).

In view B's viewDidLoad i always try to set the current date in order to track when a user "saw" that object. This is where I get the EXC_BAD_ACCESS error:

    self.currentPiece.piece_last_viewed = [[NSNumber alloc] initWithDouble:[[NSDate date] timeIntervalSince1970]];

Where self.currentPiece is the instance of a subclassed NSManagedObje开发者_开发知识库ct that was attached in A when that object existed in the database.

I know that it is being released somewhere but I don't know where since managed objects take care of much of that on their own. The error only occurs the second time around that I try to set the value.

I have tried to make this clear. Please tell me if you want me to clarify it even more. Thanks for the help (have worked on this for some hours now)

UPDATE:

Declaring the piece_last_viewed in HubPiece.h:

@interface HubPiece : NSManagedObject {

}

// ...

@property (nonatomic, retain) NSNumber *piece_last_viewed;

HubPiece.m:

@dynamic piece_last_viewed;

//...inside init method:

self.piece_last_viewed = [[NSNumber alloc] initWithDouble:[[NSDate date] timeIntervalSince1970]];

UPDATE 2:

It is not due to the switching of subviews, that is ruled out. I then realized that I didn't save my changes either, so I introduced save: inside the subclassed NSManagedObject. I then got an earlier error the first time I try to save the entity instance (which saved during an app session, but the data vanishes if I quit the app entirely and then open it up again). So I thought using [context save:&error] would be a good idea :) ...but now that doesn't work and give me a EXC_BAD_ACCESS error.

The HubPiece itself is initialized from another class HubPieceView.m :

self.currentPiece = [[HubPiece alloc] initWithXML:pieceXML];

self.currentPiece is a class variable of type HubPiece and it first declared in .h file and then synthesized in .m file.

Then inside HubPiece.m the initializer looks like this:

-(id)initWithXML:(TBXMLElement *)pieceXML
{
    // Setup the environment for dealing with Core Data and managed objects
    HenryHubAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
    NSManagedObjectContext *context = [appDelegate managedObjectContext];
    NSEntityDescription *entityHubPiece = [NSEntityDescription entityForName:@"HubPiece" 
                                                      inManagedObjectContext:context];

    // STORING values
    self = [[HubPiece alloc] initWithEntity:entityHubPiece insertIntoManagedObjectContext:context];

    // ...setting variables with normal assignment: self.var = value;

    NSError *error;

    // Save fails
    if (![context save:&error] ){
        NSLog(@" ERROR: %@", [error localizedDescription]);
    }

    return self;
}


I just realized my problem. I had been assigning values to the entity through with normal '=' assignment:

self.currentPiece.piece_last_viewed = [[NSNumber alloc] initWithDouble:[[NSDate date] timeIntervalSince1970]];

When it should have been done:

[self setCurrentPiece.piece_last_viewed:[[NSNumber alloc] initWithDouble:[[NSDate date] timeIntervalSince1970]] ];

This is because it is a managed object which creates it's own accessors at runtime through the @dynamic compiler instruction.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号