Следует ли указывать на объект NSManagedObject со слабым, а не сильным указателем?


Я думаю, что поскольку NSManagedObject управляется контекстом managedObject, указатель должен быть слабым.

Тем не менее, в моих случаях он часто возвращается к 0.
    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];

...

И все же где-то в конце строки:

tvc.categoryNearby становится нулем.

Я не знаю, как, когда и где она станет нулевой.

Как мне это отладить? Или вместо этого ссылка должна быть сильной?

Кстати, это интерфейс NearbyShortcutTVC

@interface NearbyShortcutTVC : BGBaseTableViewCell{

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

@end

Чтобы убедиться, что мы говоря об одном и том же объекте, я печатаю все адреса памяти NSArray

Они оба-один и тот же объект. Но каким-то образом свойство categoryNearby объекта волшебным образом устанавливается в нуль где-то.
 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
)

Я изменил свою функцию отладки, чтобы напечатать объект TVC и его свойство categoryNearby

Свойство categoryNearby имеет значение nil

Однако, если я сделаю ссылку сильной, это уже не ноль

-(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;
}

Результат 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"
)

Хотя проблема решена, это все еще странно. Эта категория не должна быть обнулена, даже если ссылка слабая. Это подкласс NSManagedObject, который непосредственно управляется контекстом управляемого объекта. Кроме того, тот факт, что я все еще могу получить к нему доступ, когда ссылка сильна, показывает, что объект все еще находится в памяти.

Так почему же она становится нулевой?
1 2

1 ответ:

Если вы хотите, чтобы NSManagedObject остался, вам нужно сохранить сильную ссылку на него (или поместить его в контейнер, который сильно держит его содержимое). Контекст управляемого объекта не содержит надежных ссылок на все связанные с ним объекты.

"Роль контекста управляемого объекта" в руководство по программированию основных данных говорит это:

однако по умолчанию ссылки между управляемым объектом и его контекстом являются слабыми. Этот это означает, что в общем случае вы не можете полагаться на контекст для обеспечения долговечности экземпляра управляемого объекта, и вы не можете полагаться на существование управляемого объекта для обеспечения долговечности контекста. Другими словами, то, что вы взяли какой-то предмет, не означает, что он останется.

Он продолжает объяснять случаи, когда контекст действительно сильно сохраняет объекты, и как вы можете изменить контекст, чтобы всегда сильно сохранять объекты, и как вы должны убедиться, что объекты, которые вам нужны, не освобождаются.