2014-11-26 3 views
0

После копирования. Realm-файла из папки-location1 в папку-location2 (а также сменив его имя с location1.realm на location2.realm с помощью NSFileManager) - кажется, что после этого первый вызов этого нового файла вызывает вызов миграционного блока! (т. е. setSchemaVersion). Интересно, почему ???Копирование файла realm-файла, похоже, вызывает область вызова Migration-block - почему?

Предыдущие вызовы в файл «location1/location1.realm» не вызывали вызов блока миграции, однако запросы на «location2/location2.realm» выполняются - и файлы идентичны по структуре (по крайней мере, в Realm- Браузер нет очевидной разницы) !!

Вот мой код:

ApplicatonSuppPathHandler *ApplicationSupportPathHandler = [[ApplicatonSuppPathHandler alloc] init]; 

    // creation of location where this directory shall be placed on the iPhone 
    // typically /library/Application Support/<bundleID_name>/RLMGeneralDatabasesFolderName/... 
    // = name of directory that the .realm-File finally should be placed in 
    NSString *RLMLocation1DirectoryName = folderName; 

    // if it does not exist already, create the RLMLocation_xyz-directory (.../library/Application Support/<bundleID_name>/RLMDatabasesFolderName) 
    if([ApplicationSupportPathHandler getURLToApplicationDirectoryWithSubDirectory:RLMLocation1DirectoryName] == nil) { 
     [ApplicationSupportPathHandler createSubDirectoryAtLocationToApplicationDirectory:RLMLocation1DirectoryName]; 
    } 

    // get the name of entire directory just created 
    NSURL *RLMLocation1Directory = [ApplicationSupportPathHandler getURLToApplicationDirectoryWithSubDirectory:RLMLocation1DirectoryName]; 

    // name of entire path-name (including filename !! ...needed for copy function below...) 
    NSString *RLMLocation1Path = [[RLMLocation1Directory path] stringByAppendingPathComponent:fileName]; 

    // HERE IS WHERE THE MIGRATION BLOCK IS CALLED - WHY ????? 
    // ******************************************************* 
    RLMRealm *realm_Location1 = [RLMRealm realmWithPath:RLMLocation1Path]; // pointing to realm file at path 


    // the rest does work after the migration-block call... 
    [realm_Location1 beginWriteTransaction]; 
    [realm_Location1 deleteAllObjects]; 
    [realm_Location1 addObject:RLMTopoRes]; 
    [realm_Location1 commitWriteTransaction]; 

Ниже реализация используемых классов-методы ApplicationSuppPathHandler:

@implementation ApplicatonSuppPathHandler 

- (NSURL*)getURLToApplicationDirectoryWithSubDirectory:(NSString*)SubDirectoryName { 

NSString* appBundleID = [[NSBundle mainBundle] bundleIdentifier]; 
NSFileManager*fm = [NSFileManager defaultManager]; 
NSURL* dirPath = nil; 

// Find the application support directory in the home directory. 
NSArray* appSupportDir = [fm URLsForDirectory:NSApplicationSupportDirectory 
            inDomains:NSUserDomainMask]; 
if ([appSupportDir count] > 0) 
{ 
    // Append the bundle ID and the location-Foldername to the URL for the Application Support directory 
    dirPath = [[[appSupportDir objectAtIndex:0] URLByAppendingPathComponent:appBundleID] URLByAppendingPathComponent:SubDirectoryName]; 

    BOOL isDir; 
    BOOL exists = [fm fileExistsAtPath:[dirPath path] isDirectory:&isDir]; 
    if (exists) { 
     /* file exists */ 
     if (isDir) { 
      /* path exists */ 
      return dirPath; 
     } 
     else { 
      NSLog(@"Directory does not exist"); 
      return nil; 
     } 
    } 
    else { 
     /* file does not exist */ 
     return nil; 
    } 
} 
return dirPath; 
} 

- (void)createSubDirectoryAtLocationToApplicationDirectory:(NSString*)SubDirectoryName { 

NSString* appBundleID = [[NSBundle mainBundle] bundleIdentifier]; 
NSFileManager*fm = [NSFileManager defaultManager]; 
NSURL* dirPath = nil; 

// Find the application support directory in the home directory. 
NSArray* appSupportDir = [fm URLsForDirectory:NSApplicationSupportDirectory 
            inDomains:NSUserDomainMask]; 
if ([appSupportDir count] > 0) 
{ 
    // Append the bundle ID and the location-Foldername to the URL for the Application Support directory 
    dirPath = [[[appSupportDir objectAtIndex:0] URLByAppendingPathComponent:appBundleID] URLByAppendingPathComponent:SubDirectoryName]; 

    // If the directory does not exist, this method creates it. 
    // This method call works in OS X 10.7 and later only. 
    NSError* theError = nil; 
    if (![fm createDirectoryAtURL:dirPath withIntermediateDirectories:YES attributes:nil error:&theError]) { 
     // Handle the error. 
     NSLog(@"%@", theError.localizedDescription); 
    } 
    else { 
     // Mark the directory as excluded from iCloud backups 
     if (![dirPath setResourceValue:@YES 
           forKey:NSURLIsExcludedFromBackupKey 
           error:&theError]) { 
      NSLog(@"Error excluding %@ from iCloud backup %@", [dirPath lastPathComponent], theError.localizedDescription); 
     } 
     else { 
      // NSLog(@"Location Directory excluded from iClud backups"); 
     } 
    } 
} 
} 

ответ

1

Существовал ранее ошибка в области, где новые область файлы будут иметь свои схемы версия установлена ​​в 0 вместо текущей версии схемы, что вызовет миграцию в вашем случае.

Исправление для этого была сдвинута на master ветви Realm на прошлой неделе: https://github.com/realm/realm-cocoa/pull/1142

Строительство Realm из master должны решать проблемы вы имеете. Realm v0.88.0 будет выпущен в ближайшее время с этим исправлением.

+0

Спасибо вы jpsim! Это отличная новость! Я думал, что поведение моего кода немного неожиданно (... но это иногда вполне нормально;) ...). Я с нетерпением жду Realm v0.88.0 !! Опять же - большое спасибо за быстрый ответ! – iKK

0

... hhm - похоже, другой способ перепутал!

В приведенном ниже коде показан этот метод, который загружает данные из realm-файла в объект-обертку-объект.

Возвращаясь к исходной проблеме (location2/location2.realm file create migraton-block): К сожалению, я не знал, что вызов этого метода loadData _... необходимо вызвать с осторожностью! Если он вызывается дважды - один раз в location1/location1.realm, а затем во второй раз (в location2/location2.realm), то есть когда вещи перепутались!

Я попытался создать «обертку», которая загружает и сохраняет объекты Realm. Но с Королевством это кажется более сложным, чем ожидалось. Спасибо за любые комментарии по этому поводу!

- (void) loadData_at_TopoNr_from_LocationRLM :(NSNumber *)TopoNr :(NSString *)folderName :(NSString *)fileName { 

// realm-object calling "get_TopoResultRLM_FilePath" must be of same object-type, otherwise block-migration call ! 
RLMRealm *realm = [RLMRealm realmWithPath:[self get_TopoResultRLM_FilePath :folderName :fileName]]; 

RLMResults *resTopoResult = [RLMTopoResult allObjectsInRealm:realm]; 
NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"TopoNrRLM == %d", [TopoNr intValue]]; 
RLMResults *resultTopoResult = [resTopoResult objectsWithPredicate:predicate1]; 

if ([resultTopoResult count] <= 1) { 
    if ([resultTopoResult count] == 1) { 
     // found one object 
     // data loading 
     self.TopoNrRLM = [resultTopoResult.firstObject TopoNrRLM]; 
     self.nameAnamneserRLM = [resultTopoResult.firstObject nameAnamneserRLM]; 
     self.anamneseDateRLM = [resultTopoResult.firstObject anamneseDateRLM]; 
     self.NumberOfCriteriaRLM = [resultTopoResult.firstObject NumberOfCriteriaRLM]; 
     self.BestMatchMethodRLM = [resultTopoResult.firstObject BestMatchMethodRLM]; 
     self.RealmFrameworkVersionRLM = [resultTopoResult.firstObject RealmFrameworkVersionRLM]; 
     self.BoundaryConditionVerionRLM = [resultTopoResult.firstObject BoundaryConditionVerionRLM]; 
     self.CriteriaRLM = [resultTopoResult.firstObject CriteriaRLM]; 
     self.imageNameRLM = [resultTopoResult.firstObject imageNameRLM]; 
     self.imageDataRLM = [resultTopoResult.firstObject imageDataRLM]; 
    } 
    else { .... 

Вот определение свойства оберточного-объект класса:

// GUIData-RLM 
@property (nonatomic) RLMGUIData *GUIDataRLM; 

// Location-RLM 
@property (nonatomic) RLMTopoResult *LocationRLM; 

Вот создание объекта и вызов этого loadData_at ...- метод:

RLMTopoResult *LocationRealm = [[RLMTopoResult alloc] init]; 
    [self setLocationRLM:LocationRealm]; 
    [LocationRealm loadData_at_TopoNr_from_LocationRLM :[NSNumber numberWithInt:[GUIDataRealm TopoNrRLM]] :[GUIDataRealm locationFolderNameRLM] :[NSString stringWithFormat:@"%@%s", [GUIDataRealm locationFolderNameRLM], ".realm"]];