user4951
user4951

Reputation: 33130

Should we point to an NSManagedObject entity with weak instead of strong pointer?

I think because NSManagedObject is managed by the managedObject context the pointer should be weak.

Yet it often goes back to 0 in my cases.

    for (CategoryNearby * CN in sorted) {
        //[arrayOfItems addObject:[NSString stringWithFormat:@"%@ - %d",CN.name,[CN.order intValue]]];
        NearbyShortcutTVC * tvc=[[NearbyShortcutTVC alloc]init];
        tvc.categoryNearby =CN;
//        tvc.titleString=[NSString stringWithFormat:@"%@",CN.name];
//        tvc.displayed=CN.displayed;
        [arrayOfItemsLocal addObject:tvc];
        //CN

        PO(tvc);
        PO(tvc.categoryNearby);
        while (false);
    }
    self.arrayOfItems = arrayOfItemsLocal;

    PO(self.categoriesNearbyInArrayOfItems);
    [self.tableViewa reloadData];

...

Yet somewhere down the line:

tvc.categoryNearby becomes nil.

I do not know how or when or where it become nil.

How do I debug this? Or should the reference be strong instead?

This is the interface of NearbyShortcutTVC by the way

@interface NearbyShortcutTVC : BGBaseTableViewCell{

}
@property (weak, nonatomic) CategoryNearby * categoryNearby;

@end

To make sure that we're talking about the same object I print all the memory addresses of the NSArray

They're both the exact same object. But somehow the categoryNearby property of the object is magically set to null somewhere.

 self.categoriesNearbyInArrayOfItems: (
    0x883bfe0,
    0x8b6d420,
    0x8b6f9f0,
    0x8b71de0,
    0xb073f90,
    0xb061a10,
    0xb06a880,
    0x8b74940,
    0x8b77110,
    0x8b794e0,
    0x8b7bf40,
    0x8b7cef0,
    0x8b7f4b0,
    0x8b81a30,
    0x88622d0,
    0x8864e60,
    0xb05c9a0
)

self.categoriesNearbyInArrayOfItems: (
    0x883bfe0,
    0x8b6d420,
    0x8b6f9f0,
    0x8b71de0,
    0xb073f90,
    0xb061a10,
    0xb06a880,
    0x8b74940,
    0x8b77110,
    0x8b794e0,
    0x8b7bf40,
    0x8b7cef0,
    0x8b7f4b0,
    0x8b81a30,
    0x88622d0,
    0x8864e60,
    0xb05c9a0
)

I modified my debugging function to print the TVC object and it's categoryNearby property

the categoryNearby property is set to nil

However, if I make the reference strong it's not nil anymore

-(NSArray *) categoriesNearbyInArrayOfItems
{
    NSMutableArray *categoriesArray = [NSMutableArray array];


    for (NearbyShortcutTVC * tvc in self.arrayOfItems) {
        NSString * string  = [NSString stringWithFormat:@"%p,%p",tvc,tvc.categoryNearby];
        [categoriesArray addObject:string];
    }
    return categoriesArray;
}

Result in:

2012-11-06 12:01:00.878 BadgerNew[66443:c07] self.categoriesNearbyInArrayOfItems: (
    "0x8dc96b0,0x88a58b0",
    "0x8bde780,0x88b7970",
    "0x8be0930,0x88b8870",
    "0x8bf1c00,0x88b8ca0",
    "0x8bf4070,0x8beab10",
    "0x8bf6250,0x8beaf10",
    "0x8bf8620,0x8beb390",
    "0x8bfae90,0x8beb7b0",
    "0x8b707e0,0x8bebbd0",
    "0x8b6e160,0x8bebfe0",
    "0x8b6ba10,0x8bec450",
    "0x8b69a60,0x8bec870",
    "0x8b673a0,0x8becc90",
    "0x8b648c0,0x8bed0a0",
    "0x8b62110,0x8b7dca0",
    "0x8b5f890,0x8bedbe0",
    "0xd678410,0x8bee0e0"
)
2012-11-06 12:01:10.058 BadgerNew[66443:4503] Interval for this Grab ID is 9.232143
2012-11-06 12:01:10.058 BadgerNew[66443:4503] @(data.count): 20
2012-11-06 12:01:10.414 BadgerNew[66443:c07] self.categoriesNearbyInArrayOfItems: (
    "0x8dc96b0,0x88a58b0",
    "0x8bde780,0x88b7970",
    "0x8be0930,0x88b8870",
    "0x8bf1c00,0x88b8ca0",
    "0x8bf4070,0x8beab10",
    "0x8bf6250,0x8beaf10",
    "0x8bf8620,0x8beb390",
    "0x8bfae90,0x8beb7b0",
    "0x8b707e0,0x8bebbd0",
    "0x8b6e160,0x8bebfe0",
    "0x8b6ba10,0x8bec450",
    "0x8b69a60,0x8bec870",
    "0x8b673a0,0x8becc90",
    "0x8b648c0,0x8bed0a0",
    "0x8b62110,0x8b7dca0",
    "0x8b5f890,0x8bedbe0",
    "0xd678410,0x8bee0e0"
)

While the problem is solved, it's still strange. That categoryNearby should not be nilled even if the reference is weak. It's a subclass of NSManagedObject that's directly managed by the managed object context. Also the fact that I can still access it when the reference is strong shows that the object is still in memory.

So how come it becomes nil?

Upvotes: 3

Views: 1341

Answers (1)

rob mayoff
rob mayoff

Reputation: 385870

If you want an NSManagedObject to stay around, you need to keep a strong reference to it (or put it in a container that strongly holds its contents). The managed object context does not keep strong references to all of the objects associated with it.

“The Role of the Managed Object Context” in the Core Data Programming Guide says this:

By default, though, the references between a managed object and its context are weak. This means that in general you cannot rely on a context to ensure the longevity of a managed object instance, and you cannot rely on the existence of a managed object to ensure the longevity of a context. Put another way, just because you fetched an object doesn’t mean it will stay around.

It goes on to explain the times when the context does strongly retain objects, and how you can change the context to always strongly retain objects, and how you should make sure the objects you need are not deallocated.

Upvotes: 8

Related Questions