Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c CoreData SQLite存储图像数据失败_Objective C_Sqlite_Core Data_Ios7_Blob - Fatal编程技术网

Objective c CoreData SQLite存储图像数据失败

Objective c CoreData SQLite存储图像数据失败,objective-c,sqlite,core-data,ios7,blob,Objective C,Sqlite,Core Data,Ios7,Blob,我在CoreData(SQLite store)中存储图像(JPEG)已经有一段时间了,没有问题。我最近不得不从一个外部源导入一些数据,它似乎可以很好地处理新数据。我刚刚遇到了一个数据实例,其中应用了以下内容: 1.实体加载并具有相关信息 2.实体关系将被恢复 3.包含NSData属性的实体为该属性返回nil 4.当我查询该对象的备份存储时,它在等价列中显示二进制数据 当我进一步查看存储时,问题行似乎只有38字节的信息存储在二进制数据列中。在处理的所有图像中,始终有30%的图像存储了这38字节的

我在CoreData(SQLite store)中存储图像(JPEG)已经有一段时间了,没有问题。我最近不得不从一个外部源导入一些数据,它似乎可以很好地处理新数据。我刚刚遇到了一个数据实例,其中应用了以下内容: 1.实体加载并具有相关信息 2.实体关系将被恢复 3.包含NSData属性的实体为该属性返回nil 4.当我查询该对象的备份存储时,它在等价列中显示二进制数据

当我进一步查看存储时,问题行似乎只有38字节的信息存储在二进制数据列中。在处理的所有图像中,始终有30%的图像存储了这38字节的数据,而其余图像则存储了完全准确和正确的数据

导入进程在后台线程中运行。为了管理4.5Gb图像数据的内存需求,我以100-1000的批量运行导入(最初为1000,但尝试了100,以查看是否有任何差异)。我在批处理开始时创建nsmanagedobjectcontext,处理批处理,然后保存上下文。在处理过程中,我会记录分配给相关对象的NSData属性的数据长度,并且这些数据在时间上100%准确。然而,当数据被保存,我在商店里看30%只有38字节的数据。我还尝试在创建每个对象后保存上下文,但结果相同,为30%

我有一种强烈的感觉,有一种多线程的元素把我的导入过程搞砸了,但我在网上找不到任何关于这一点的东西。希望CoreData专家能提供一些关于我的数据到底是怎么回事的信息

编辑:代码的一个子集(在导入过程中有很多其他内容,但是图像导入是合理的线性的)

processPhoto方法

+(NSString*)processPhoto:(NSArray*)data withRefDate:(NSDate*)refDate intoContext:(NSManagedObjectContext*)liveContext// withData:(bool)saveData
{
    if(data.count!=10)
         return [NSString stringWithFormat:@"Expected 10 items, found %d",[data count]];
    NSString *partialPath = [data objectAtIndex:8];
    if([partialPath isEqualToString:@"NULL"])
        return nil;
    NSString *filePath = [[[PRModel sharedInstance] applicationDocumentsDirectory] stringByAppendingPathComponent:partialPath];
    if(![[NSFileManager defaultManager] fileExistsAtPath:filePath])
    {
        return [NSString stringWithFormat:@"File not found for %@",filePath];
    }
    // Got everything we need so create a photo
    PhotoEntity *photo = [NSEntityDescription insertNewObjectForEntityForName:@"Photo" inManagedObjectContext:liveContext];
    photo.photoID = [data objectAtIndex:9];
    photo.imageType = @"PHOTO";
    photo.photoDescription = @"";
    UIImage *photoImage = [[UIImage alloc]initWithContentsOfFile:filePath];
    [photo setImage:photoImage inContext:liveContext];
    [photoImage release];
    return nil;
}
setImage方法是实际设置数据的地方

-(void)setImage:(UIImage *)image inContext:(NSManagedObjectContext *)context
{        
    if(self.photoData==nil)
    {
        // Create a new photo data entity
        self.photoData = [NSEntityDescription insertNewObjectForEntityForName:@"PhotoData" inManagedObjectContext:context];
    }
UIImage *resizedImage = [image copyImageResizedWithLength:MAX_STORE_RESOLUTION interpolationQuality:kCGInterpolationHigh];
    NSData *data = UIImageJPEGRepresentation(resizedImage, 0.6);
    NSLog(@"ImageLength=%d",[data length]);
    self.photoData.imageData = data;
    [resizedImage release];
}

因此,此代码在70%的情况下有效,但在30%的情况下失败。。。在这方面还有很多其他的东西,但是处理图像的代码在这个领域已经稳定了至少6个月,有500个用户,所以这肯定与我在海量对象背景线程过程中使用它有关。

唉。。。事实证明,CoreData现在决定将大于130Kb的文件存储为外部数据。我在存储中看到的38个字节是与外部文件相关的Guid。现在,我需要弄清楚为什么在我的应用程序主体中,当有明确的数据存在时,有效数据返回为零

编辑:
好的,也解决了丢失数据的问题。我需要在模拟器上运行导入以最大化可用RAM。然后我将数据库(减去外部数据文件夹,因为我不知道它在那里)转移到iPad上进行测试。。。当应用程序加载数据时,它尝试检索外部数据文件,但找不到该文件,因此将数据属性加载为nil。没有任何异常或错误表明这种情况是令人沮丧的。

您应该展示如何在后台导入,尤其是谁设置了上下文以及如何建立关系。另一方面:最好不要直接将图像存储在CoreData中……注意,图像>500K左右应该存储在外部,但调整大小和压缩的重点是确保图像在60K-120K范围内。该应用已经在该领域应用了3年,图像处理基本相同,从未遇到过这样的错误。除了大量数据导入(42000张图像)之外,数据库通常在任何时候都只存储1000-2000张图像。失败率似乎是从第一次保存开始的,因此我认为这不是容量问题……如果后台线程中的托管对象上下文是以一种可以在并发设置中使用的方式创建的,那么从代码中看,这一点并不明显。我的通信后台线程使用相同的基本过程,没有问题。(工作)comm线程和(不工作)import线程之间的关键区别在于,comm线程必须等待图像数据通过网络传输,然后才能保存,这样循环就不会“太紧”,因为大数据不会进入CD sqlite数据库。这不是答案。请编辑问题,而不是发布不是答案的答案;)谢谢
+(NSString*)processPhoto:(NSArray*)data withRefDate:(NSDate*)refDate intoContext:(NSManagedObjectContext*)liveContext// withData:(bool)saveData
{
    if(data.count!=10)
         return [NSString stringWithFormat:@"Expected 10 items, found %d",[data count]];
    NSString *partialPath = [data objectAtIndex:8];
    if([partialPath isEqualToString:@"NULL"])
        return nil;
    NSString *filePath = [[[PRModel sharedInstance] applicationDocumentsDirectory] stringByAppendingPathComponent:partialPath];
    if(![[NSFileManager defaultManager] fileExistsAtPath:filePath])
    {
        return [NSString stringWithFormat:@"File not found for %@",filePath];
    }
    // Got everything we need so create a photo
    PhotoEntity *photo = [NSEntityDescription insertNewObjectForEntityForName:@"Photo" inManagedObjectContext:liveContext];
    photo.photoID = [data objectAtIndex:9];
    photo.imageType = @"PHOTO";
    photo.photoDescription = @"";
    UIImage *photoImage = [[UIImage alloc]initWithContentsOfFile:filePath];
    [photo setImage:photoImage inContext:liveContext];
    [photoImage release];
    return nil;
}
-(void)setImage:(UIImage *)image inContext:(NSManagedObjectContext *)context
{        
    if(self.photoData==nil)
    {
        // Create a new photo data entity
        self.photoData = [NSEntityDescription insertNewObjectForEntityForName:@"PhotoData" inManagedObjectContext:context];
    }
UIImage *resizedImage = [image copyImageResizedWithLength:MAX_STORE_RESOLUTION interpolationQuality:kCGInterpolationHigh];
    NSData *data = UIImageJPEGRepresentation(resizedImage, 0.6);
    NSLog(@"ImageLength=%d",[data length]);
    self.photoData.imageData = data;
    [resizedImage release];
}