У меня есть пользовательский объект (Data
), наследующий от NSObject
, который должен быть сохранен в основных данных. Поэтому я создал NSManagedObject
(Transaction
), который содержит Data
, что-то вроде этого:Основные данные не возвращают корректные данные иногда
@interface Transaction (CoreDataProperties)
@property (nonatomic) BOOL m_isUploaded;
@property (nullable, nonatomic, retain) id m_transactionData; // this is the Data class, stored under Transformable
@property (nonatomic) int64_t m_submitDateTimeEpochMilliseconds;
@property (nullable, nonatomic, retain) NSString *m_uuid;
@end
я создал один контекст и сделал все, что связано с контекстом в основном потоке.
Я сделал Data
соответствует протоколам NSCoding
и NSCopying
. Кроме того, некоторые пользовательские классы, используемые в Data
, также соответствуют NSCoding
.
Это короткая выдержка из Data.h
:
@interface Data : NSObject <NSCoding, NSCopying>
@property (strong, nonatomic, nullable) HeldItem *m_heldItem;
@property (strong, nonatomic, nullable) NSDecimalNumber *m_discountAmount;
@property (strong, nonatomic, nonnull) NSMutableArray<Record *> *m_records;
@property (strong, nonatomic, nonnull) NSString *m_transactionId;
@property (nonatomic) CLLocationCoordinate2D m_location;
@property (strong, nonatomic, nullable) NSString *m_status;
- (void)encodeWithCoder:(nonnull NSCoder *)aCoder;
- (nonnull id)initWithCoder:(nonnull NSCoder *)aDecoder;
...lots of variables/methods here...
@end
Если я чисто просто вставить, нет никаких проблем (я подтвердил это, глядя на переменные во encodeWithCoder:
). Или, если я делаю чистое чтение, проблем нет.
Однако, если бы я, чтобы вставить новую Transaction
(и Data
) запись и поиск/прочитать существующую запись и изменить его (Data
), существующая запись не спасутся, и новый рекорд в основном пустой (как будто новый). Эта проблема возникает при случайных. Я могу запустить его 8 раз, прежде чем столкнуться с этой ситуацией.
Любая идея, где я, возможно, пошла не так? Я застрял довольно долго.
Это та часть, где он, кажется, дает мне проблему:
// Store the existing/new data into Core Data
Transaction *t = [MANAGER createTransaction];
Data *data = [Data new];
t.m_kmsTransactionData = data;
// ...some assigning stuffs to other variables...
// ========== if this whole section is omitted the newly created record saves fine =========
Transaction *old = [MANAGER getTransactionFromCoreDataWithId:someOldDataIdString];
// oldData sometimes is returning a blank object (i.e. booleans are no, objects are nil etc)
Data *oldData = [old.m_kmsTransactionData mutableCopy];
oldData.m_status = @"old"; // testing to see if the old record gets updated
old.m_isUploaded = NO;
old.m_kmsTransactionData = [oldData copy];
// This doesn't work because oldData.m_transactionId is nil
data.m_transactionId = [MANAGER generateNewTransactionIDBasedOn:oldData.m_transactionId];
//===============================================
// ... more assigning code here ....
// Save context
[MANAGER saveDatabase];
-
// Some helper function in some manager
- (Transaction * _Nonnull)getTransactionFromCoreDataWithId:(NSString * _Nonnull)dataId
{
NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:[Transaction entityName]];
request.returnsObjectsAsFaults = NO;
NSError *error;
NSArray<Transaction *> *fetchedObjects = [self.m_coreDataStore.managedObjectContext executeFetchRequest:request error:&error];
NSAssert(fetchedObjects != nil, @"Failed to execute %@: %@", request, error);
if(fetchedObjects == nil || fetchedObjects.count == 0)
{
// error
return nil;
}
for(Transaction *t in fetchedObjects)
{
Data *td = t.m_kmsTransactionData;
if([td.m_salesRecordId isEqualToString:salesRecordId])
{
return t;
}
}
return nil;
}
где вы экономить?почему ваш класс не является подклассом «NSManagedObject»? Вы сериализуете 'Data' в экземпляры' Transaction'? – Wain
Мои «данные» уже были созданы как «NSObject», и поскольку мне нужно хранить «данные», чтобы он сохранялся, а также отслеживал, что я сделал с «данными», я создал «транзакцию» для их хранения , Я спасаю в конце всего. Позвольте мне исправить код. – CyberMew
Можете ли вы включить отладку компакт-диска «-com.apple.CoreData.SQLDebug 1» в разделе «Аргументы, переданные при запуске». Интересно, будет ли CD автоматически использовать NSKeyedArchiver для упаковки/распаковки вашего объекта. – Andy