• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Managed Object won't dealloc even after Hit with Kitchen Sink
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Managed Object won't dealloc even after Hit with Kitchen Sink


  • Subject: Managed Object won't dealloc even after Hit with Kitchen Sink
  • From: Jerry Krinock <email@hidden>
  • Date: Sun, 21 Dec 2008 21:17:44 -0800

REAL-LIFE PROBLEM

In a managed memory application, I have a managed object which, besides its Core Data managed properties, has a single instance variable, a worker-kind of object which does some heavy lifting for it. So that this retained worker, etc., will be deallocced, I need this managed object to get deallocced when no longer needed.

The documentation [1] seems very clear that, although the 'insert...' methods return an autoreleased NSManagedObject, a managed object may be retained by:
(a) the managed object context, until changes are saved
or rolled back, or,
(b) the managed object context's undo manager, as long as
an action involving the managed object remains on
the undo stack.


I conclude that if I save or roll back the moc, and reset the undo stack, my managed object should be deallocced with the next autorelease. But despite my repeatedly doing so, these managed objects never dealloc.

STUDY - DEMO APP

To investigate, I modified Apple's Low-Level Core Data Tutorial into The World's Simplest Core Data Tool [3] which simply does this:

   1.  Create a Core Data in-memory stack
   2.  Disable undo registration
   3.  Insert a managed object Foo
   4.  Roll back the moc
   5.  Save the moc
   6.  Remove all actions from undo manager
   7.  Reset the moc

Redundant, I know, but despite my so throwing the kitchen sink at it, when I then

   8.  Release the autorelease pool

and expect that my Foo should log a dealloc message, it doesn't happen.

Removing some of the redundant steps does not help. It does dealloc (with no crash) if I send it TWO release messages.

?????

What am I not understanding? Eric Wing was wondering the same thing, never got a reply [2].

Thanks,

Jerry Krinock


[1] http://developer.apple.com/DOCUMENTATION/Cocoa/Conceptual/CoreData/Articles/cdMemory.html#/ /apple_ref/doc/uid/TP40001860


[2]  http://www.cocoabuilder.com/archive/message/cocoa/2005/9/27/147040

[3]  The World's Simplest Core Data Tool

// To see the action, scroll down to main(),

#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>

@interface Foo : NSManagedObject {
}

@end

@implementation Foo

// This is just to log init and dealloc.

- (id)initWithEntity:(NSEntityDescription*)entity
insertIntoManagedObjectContext:(NSManagedObjectContext*)moc {
    self = [super initWithEntity:entity
insertIntoManagedObjectContext:moc] ;

    NSLog(@"Initted %@", self) ;
    return self ;
}

- (void)dealloc {
    NSLog(@"Dealloccing %@", self) ;
    [super dealloc] ;
}


@end


// Functions to create Core Data Stack

NSManagedObjectModel *managedObjectModel() {

    static NSManagedObjectModel *mom = nil;

    if (mom != nil) {
        return mom;
    }

    mom = [[NSManagedObjectModel alloc] init];

NSEntityDescription *runEntity = [[NSEntityDescription alloc] init];
[runEntity setName:@"Foo"];
[runEntity setManagedObjectClassName:@"Foo"];
[mom setEntities:[NSArray arrayWithObject:runEntity]];


    return mom;
}

NSManagedObjectContext *managedObjectContext() {

    static NSManagedObjectContext *moc = nil;

    if (moc != nil) {
        return moc;
    }

    moc = [[NSManagedObjectContext alloc] init];

    NSPersistentStoreCoordinator *coordinator =
    [[NSPersistentStoreCoordinator alloc]
     initWithManagedObjectModel: managedObjectModel()];
    [moc setPersistentStoreCoordinator: coordinator];

NSError *error;
NSPersistentStore *newStore ;
newStore = [coordinator addPersistentStoreWithType:NSInMemoryStoreType
configuration:nil
URL:nil
options:nil
error:&error];


    if (newStore == nil) {
        NSLog(@"Store Configuration Failure\n%@",
              ([error localizedDescription] != nil) ?
              [error localizedDescription] : @"Unknown Error");
    }
    return moc;
}


// The action...

int main (int argc, const char * argv[])
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

// Get Core Data stack and stuff
NSManagedObjectModel *mom = managedObjectModel();
NSManagedObjectContext *moc = managedObjectContext();
NSUndoManager* undoManager = [moc undoManager] ;
NSEntityDescription *runEntity = [[mom entitiesByName] objectForKey:@"Foo"];


    // Insert a Foo without telling the undo manager
    [undoManager disableUndoRegistration] ;
    Foo *foo = [[Foo alloc] initWithEntity:runEntity
            insertIntoManagedObjectContext:moc];

    [moc rollback] ;

    // In case rollback was not enough to make that moc give up
    // my foo, save the moc
    NSError *error = nil;
    if (![managedObjectContext() save: &error]) {
        NSLog(@"Error while saving\n%@",
              ([error localizedDescription] != nil)
              ? [error localizedDescription] : @"Unknown Error");
        exit(1);
    }

    // As a further attempt to make sure that the undo manager
    // is not holding a reference to our Foo,
    [undoManager removeAllActions] ;

    // Now, for a final nail in foo's coffin...
    [moc reset] ;

    // Now, NOBODY has any reason to hold on to foo, so
    // when we release the pool, we expect that Foo should
    // log a dealloc message:

    [pool release];

    // Actual result: no dealloc

    // Experiment: If I send foo ^two^ release messages:
    // [foo release] ;
    // [foo release] ;
    // Then it will dealloc, with no crash.
    // A third release message,
    // [foo release] ;
    // will cause a crash.

    NSLog(@"Terminating") ;

    return 0;
}

_______________________________________________

Cocoa-dev mailing list (email@hidden)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


  • Follow-Ups:
    • Re: Managed Object won't dealloc even after Hit with Kitchen Sink
      • From: Jim Correia <email@hidden>
    • Re: Managed Object won't dealloc even after Hit with Kitchen Sink
      • From: Quincey Morris <email@hidden>
  • Prev by Date: Need advice on creating a new document from within another document
  • Next by Date: Color space for cmyk eps images converting to rgb
  • Previous by thread: Need advice on creating a new document from within another document
  • Next by thread: Re: Managed Object won't dealloc even after Hit with Kitchen Sink
  • Index(es):
    • Date
    • Thread