Reputation: 33130
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
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