memory management issue?

  • Hi,

    I'm still pretty new to Cocoa and have just learned the hard way about
    memory management.  My app keeps dying in the function below.  I've
    gone back and cleaned up my classes according to the Memory Management
    Rules (http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/Tasks/
    MemoryManagementRules.html#/

    /apple_ref/doc/uid/20000994), but it doesn't seem to help.  The first
    and second time that this function gets accessed it works, no
    problem.  The third time it gets called it dies at:

    array = [moc executeFetchRequest:request error:&error];

    I put a breakpoint in right before it, and all the variables appear to
    be in line. I've been stuck on it for a couple weeks now, so if anyone
    has any suggestion of how I can better debug it, I'd really appreciate
    it.

    The error message that I get is: Program received signal:
    “EXC_BAD_ACCESS”.

    And here is the function:

    - (void) getSelectedBuyer:(NSString*)uid
    {

    NSManagedObjectModel *mom = [self managedObjectModel];
    NSManagedObjectContext *moc = [self managedObjectContext];
    NSEntityDescription *buyerEntity = [[mom entitiesByName]
    objectForKey:@"Buyer"];

    NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
    [request setEntity:buyerEntity];

    NSPredicate *predicate = [NSPredicate predicateWithFormat: @"active =
    YES AND uid = %@", uid];
    [request setPredicate:predicate];

    NSError *error = nil;
    NSArray *array;

    array = [moc executeFetchRequest:request error:&error];

    if ((error != nil) || (array == nil)) {

      NSLog(@"Error while fetching\n%@",
      ([error localizedDescription] != nil) ? [error
    localizedDescription] : @"Unknown Error");
      exit(1);
    }

    NSEnumerator *buyerEnumerator = [array objectEnumerator];

    [buyer release];
    buyer = [buyerEnumerator nextObject];
    [buyer setAddressBook];

    }

    Thanks,
    Steven
  • On Feb 1, 2008, at 11:13 AM, Steven Crosley wrote:

    > Hi,
    >
    > I'm still pretty new to Cocoa and have just learned the hard way
    > about memory management.  My app keeps dying in the function below.
    > I've gone back and cleaned up my classes according to the Memory
    > Management Rules (http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/Tasks/
    MemoryManagementRules.html#/

    > /apple_ref/doc/uid/20000994), but it doesn't seem to help.  The
    > first and second time that this function gets accessed it works, no
    > problem.  The third time it gets called it dies at:
    >
    > array = [moc executeFetchRequest:request error:&error];
    >
    > I put a breakpoint in right before it, and all the variables appear
    > to be in line. I've been stuck on it for a couple weeks now, so if
    > anyone has any suggestion of how I can better debug it, I'd really
    > appreciate it.
    >
    > The error message that I get is: Program received signal:
    > “EXC_BAD_ACCESS”.
    >

    Have you tired releasing the fetch request at the end of the function
    instead of autoreleaseing it?

    Have you tired using NSZombiesEnabled?  http://www.cocoadev.com/index.pl?NSZombieEnabled

    Adhamh
  • Hey Adhamh,

    I did try releasing it at the end of the function, but same result.  I
    haven't looked at NSZombiesEnabled, I'll try that.  Thanks for the
    quick response.

    Steven

    On Feb 1, 2008, at 11:25 AM, Adhamh Findlay wrote:

    >
    > On Feb 1, 2008, at 11:13 AM, Steven Crosley wrote:
    >
    >> Hi,
    >>
    >> I'm still pretty new to Cocoa and have just learned the hard way
    >> about memory management.  My app keeps dying in the function
    >> below.  I've gone back and cleaned up my classes according to the
    >> Memory Management Rules (http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/Tasks/
    MemoryManagementRules.html#/

    >> /apple_ref/doc/uid/20000994), but it doesn't seem to help.  The
    >> first and second time that this function gets accessed it works, no
    >> problem.  The third time it gets called it dies at:
    >>
    >> array = [moc executeFetchRequest:request error:&error];
    >>
    >> I put a breakpoint in right before it, and all the variables appear
    >> to be in line. I've been stuck on it for a couple weeks now, so if
    >> anyone has any suggestion of how I can better debug it, I'd really
    >> appreciate it.
    >>
    >> The error message that I get is: Program received signal:
    >> “EXC_BAD_ACCESS”.
    >>
    >
    > Have you tired releasing the fetch request at the end of the
    > function instead of autoreleaseing it?
    >
    > Have you tired using NSZombiesEnabled?  http://www.cocoadev.com/index.pl?NSZombieEnabled
    >
    > Adhamh
  • On 02/02/2008, at 4:13 AM, Steven Crosley wrote:

    > [buyer release];
    > buyer = [buyerEnumerator nextObject];

    You're not retaining buyer. Where do you do that?

    - Chris
  • Thanks for all the suggestions.  I changed the function based on them,
    and now it dies the fifth or sixth time I access it, but on the third
    time I get a more friendly error message:

    [NSCFString valueForProperty:]: unrecognized selector sent to instance
    0x1b90e0

    So at least there's progress.  Thanks again!

    Steven

    - (void) getSelectedBuyer:(NSString*)uid
    {

    NSAssert( uid != nil, @"Should have gotten a uid");
    NSManagedObjectContext *moc = [self managedObjectContext];
    NSAssert( moc != nil, @"What, no MOC?");
    NSEntityDescription *buyerEntity = [NSEntityDescription
    entityForName:@"Buyer" inManagedObjectContext:moc];
    NSAssert( buyerEntity != nil, @"Should have gotten an entity");

    NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
    [request setEntity:buyerEntity];

    NSPredicate *predicate = [NSPredicate predicateWithFormat: @"active =
    YES AND uid = %@", uid];
    [request setPredicate:predicate];

    NSError *error = nil;
    NSArray *array;

    array = [moc executeFetchRequest:request error:&error];

    if ((error != nil) || (array == nil)) {

      NSLog(@"Error while fetching\n%@",
      ([error localizedDescription] != nil) ? [error
    localizedDescription] : @"Unknown Error");
      exit(1);
    }

    NSEnumerator *buyerEnumerator = [array objectEnumerator];

    [buyer release];
    buyer = [[buyerEnumerator nextObject] retain];
    NSLog(@"%@", [buyer uid]);
    [buyer setAddressBook];

    }

    On Feb 1, 2008, at 11:46 AM, Chris Suter wrote:

    >
    > On 02/02/2008, at 4:13 AM, Steven Crosley wrote:
    >
    >> [buyer release];
    >> buyer = [buyerEnumerator nextObject];
    >
    > You're not retaining buyer. Where do you do that?
    >
    > - Chris
    >
  • On Feb 1, 2008, at 10:29 AM, Steven Crosley wrote:

    > [NSCFString valueForProperty:]: unrecognized selector sent to
    > instance 0x1b90e0

    Sounds like a message sent to a deallocated object, something that
    using NSZombieEnabled would help you troubleshoot. Give it a try!

    j o a r
  • Looks like it was an issue with the setAddressBook function.  Works
    like a charm now, and I think I more fully understand how memory
    management works.  Thanks again for all your help!

    Before suggestions:

    - (void)setAddressBook
    {
    book = [ABAddressBook sharedAddressBook];
    person = (ABPerson *)[book recordForUniqueId:[self uid]];
    }

    After suggestions:

    - (void)setAddressBook
    {
    [book release];
    [person release];
    book = [[ABAddressBook sharedAddressBook] retain];
    person = (ABPerson *)[[book recordForUniqueId:[self uid]] retain];
    }

    On Feb 1, 2008, at 12:51 PM, j o a r wrote:

    >
    > On Feb 1, 2008, at 10:29 AM, Steven Crosley wrote:
    >
    >> [NSCFString valueForProperty:]: unrecognized selector sent to
    >> instance 0x1b90e0
    >
    >
    > Sounds like a message sent to a deallocated object, something that
    > using NSZombieEnabled would help you troubleshoot. Give it a try!
    >
    > j o a r
    >
    >
  • On 1 Feb 2008, at 19:33, Steven Crosley wrote:

    > Looks like it was an issue with the setAddressBook function.  Works
    > like a charm now, and I think I more fully understand how memory
    > management works.  Thanks again for all your help!
    >
    > Before suggestions:
    >
    > - (void)setAddressBook
    > {
    > book = [ABAddressBook sharedAddressBook];
    > person = (ABPerson *)[book recordForUniqueId:[self uid]];
    > }
    >
    >
    > After suggestions:
    >
    > - (void)setAddressBook
    > {
    > [book release];
    > [person release];
    > book = [[ABAddressBook sharedAddressBook] retain];
    > person = (ABPerson *)[[book recordForUniqueId:[self uid]] retain];
    > }

    There's a big possible flaw here. What if the old and new book or
    person objects are the same? You'll release the object, and if that
    deallocs it, the next code will attempt to retain a dead object.
    Admittedly in this particular case it's pretty unlikely, but it's good
    general practice for accessor methods of all kinds.
    >
    >
    > On Feb 1, 2008, at 12:51 PM, j o a r wrote:
    >
    >>
    >> On Feb 1, 2008, at 10:29 AM, Steven Crosley wrote:
    >>
    >>> [NSCFString valueForProperty:]: unrecognized selector sent to
    >>> instance 0x1b90e0
    >>
    >>
    >> Sounds like a message sent to a deallocated object, something that
    >> using NSZombieEnabled would help you troubleshoot. Give it a try!
    >>
    >> j o a r
    >>
    >>

  • Have you read the Cocoa memory management guide? It covers accessors:

    <http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/Articl
    es/mmAccessorMethods.html#//apple_ref/doc/uid/TP40003539
    >

    --
    m-s

    On 01 Feb, 2008, at 14:33, Steven Crosley wrote:

    > Looks like it was an issue with the setAddressBook function.  Works
    > like a charm now, and I think I more fully understand how memory
    > management works.  Thanks again for all your help!
    >
    > Before suggestions:
    >
    > - (void)setAddressBook
    > {
    > book = [ABAddressBook sharedAddressBook];
    > person = (ABPerson *)[book recordForUniqueId:[self uid]];
    > }
    >
    >
    > After suggestions:
    >
    > - (void)setAddressBook
    > {
    > [book release];
    > [person release];
    > book = [[ABAddressBook sharedAddressBook] retain];
    > person = (ABPerson *)[[book recordForUniqueId:[self uid]] retain];
    > }
    >
    > On Feb 1, 2008, at 12:51 PM, j o a r wrote:
    >
    >>
    >> On Feb 1, 2008, at 10:29 AM, Steven Crosley wrote:
    >>
    >>> [NSCFString valueForProperty:]: unrecognized selector sent to
    >>> instance 0x1b90e0
    >>
    >>
    >> Sounds like a message sent to a deallocated object, something that
    >> using NSZombieEnabled would help you troubleshoot. Give it a try!
    >>
    >> j o a r
    >>
    >>

  • On 02/02/2008, at 7:38 AM, Mike Abdullah wrote:

    >> - (void)setAddressBook
    >> {
    >> [book release];
    >> [person release];
    >> book = [[ABAddressBook sharedAddressBook] retain];
    >> person = (ABPerson *)[[book recordForUniqueId:[self uid]] retain];
    >> }
    >
    > There's a big possible flaw here. What if the old and new book or
    > person objects are the same? You'll release the object, and if that
    > deallocs it, the next code will attempt to retain a dead object.
    > Admittedly in this particular case it's pretty unlikely, but it's
    > good general practice for accessor methods of all kinds.

    There is no flaw here, or at least not the flaw you're suggesting.
    [ABAddressBook sharedAddressBook] should always return a valid object,
    as will recordForUniqueID. Your comment would make sense if something
    was being passed as a parameter but it's not in this case.

    The only possible flaw I can see is if sharedAddressBook: or
    recordForUniqueId: were to throw exceptions (I don't know if they do
    or not, I haven't checked), in which case book and person wouldn't be
    valid. The solution here would be to to set them to nil after
    releasing them or you could use garbage collection instead.

    - Chris
previous month february 2008 next month
MTWTFSS
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29    
Go to today