我正在使用REALM版本0.98.1(对于Objective C),有时获取“ Bad Realm文件头”异常,而压缩DB大小强大>在应用启动时。
以下是AppDelegate应用程序中调用序列的方法didFinishLaunch ....
[self setDefaultConfigrutaionForRealm];
[self vacuumRealm];
以下是配置领域的代码:
+(void)setDefaultConfigrutaionForRealm{
RLMRealmConfiguration * defCongfig = [RLMRealmConfiguration defaultConfiguration];
defCongfig.path = REALM_PATH(REALM_FILE_NAME);
defCongfig.schemaVersion = SCHEMA_VERSION;
[RLMRealmConfiguration setDefaultConfiguration:defCongfig];
}
以下是VacuumRealm(压缩数据库大小)的代码:
+ (void)vacuumRealm {
@try{
@autoreleasepool {
RLMRealm *realm = [RLMRealm defaultRealm];
NSString *realmPath = [realm path];
NSLog(@"vacuumRealm realmPath = %@", realmPath);
long long fileSize = [[[NSFileManager defaultManager] attributesOfItemAtPath:realmPath error:nil][NSFileSize] longLongValue];
NSLog(@"vacuumRealm ENTER filesize = %llu", fileSize);
//
NSError *err;
BOOL success;
NSDate *startDate = [NSDate date];
NSString *copyPath = [realmPath stringByAppendingString:@".copy"];
[[NSFileManager defaultManager] removeItemAtPath:copyPath error:&err];
success = [realm writeCopyToPath:copyPath error:&err];
if (success) {
success = [[NSFileManager defaultManager] removeItemAtPath:realmPath error:&err];
if (success) {
success = [[NSFileManager defaultManager] copyItemAtPath:copyPath toPath:realmPath error:&err];
if (success) {
[[NSFileManager defaultManager] removeItemAtPath:copyPath error:&err];
NSDate *endDate = [NSDate date];
NSTimeInterval executionTime = [endDate timeIntervalSinceDate:startDate];
NSLog(@"vacuumRealm cleanup took %f ms", executionTime);
}
}
}
//
fileSize = [[[NSFileManager defaultManager] attributesOfItemAtPath:realmPath error:nil][NSFileSize] longLongValue];
NSLog(@"vacuumRealm EXIT filesize = %llu", fileSize);
}
}
@catch (NSException *exception) {
NSLog(@"Inside vacuumRealm exception = %@",exception.description);
}
@finally {
}
}
调试时我观察到的域路径已在“ setDefaultConfigrutaionForRealm ”方法中正确配置(附加屏幕截图供参考),但一旦调用“ vacuumRealm ”方法我我在下面的行中收到“ Bad Realm文件标题(#1)”:
RLMRealm *realm = [RLMRealm defaultRealm];
解决此异常的任何帮助都会非常有用。
提前致谢。
答案 0 :(得分:1)
您正在创建一个Realm实例(RLMRealm *realm = [RLMRealm defaultRealm];
)并从中删除该文件而不释放该实例。这会导致您看到的损坏等问题,因为您正在修改文件,而Realm仍在访问它。
以下是您的方法的更新版本(省略调试日志和err
,因为它没有被使用):
__block BOOL copySuccess = NO;
NSString *realmPath = [[RLMRealmConfiguration defaultConfiguration] path];
NSString *copyPath = [realmPath stringByAppendingString:@".copy"];
@autoreleasepool {
[[NSFileManager defaultManager] removeItemAtPath:copyPath error:nil];
copySuccess = [[RLMRealm defaultRealm] writeCopyToPath:copyPath error:nil];
}
if (copySuccess && [[NSFileManager defaultManager] removeItemAtPath:realmPath error:nil]) {
[[NSFileManager defaultManager] moveItemAtPath:copyPath toPath:realmPath error:nil];
}
此外,在此过程中抛出的任何异常都不是可以恢复的。所以在@catch
块中唯一安全的做法是中止。或者根本没有@try
/ @catch
条款。