我在单独的后台操作中更新领域对象,并在操作块本身中创建了Realm实例,但仍然收到此错误。有什么线索吗?
- (void)didFavoriteButtonTapped:(FlickerPhotoCell *)photoCell {
NSIndexPath *indexPath = [self.collectionView indexPathForCell:photoCell];
FlickerPhoto *photo = [self.photos objectAtIndex:indexPath.item];
photoCell.photoFavouriteButton.selected = !photo.isFavorited;
[self.opQueue addOperationWithBlock:^{
RLMRealm *realm = [RLMRealm defaultRealm];
[realm beginWriteTransaction];
photo.isFavorited = !photo.isFavorited;
[realm commitWriteTransaction];
//Saving in local database
NSPredicate *pred = [NSPredicate predicateWithFormat:@"photoURL == %@ AND isFavorited == YES", photo.photoURL];
RLMResults *searchedPhotos = [FlickerPhoto objectsWithPredicate:pred];
FlickerPhoto *photoInDatabase = [searchedPhotos firstObject];
BOOL isPhotoExists = (photoInDatabase != nil);
if(photo.isFavorited) {
if(!isPhotoExists) {
[realm transactionWithBlock:^{
[realm addObject:photo];
}];
}
} else {
if(isPhotoExists) {
[realm beginWriteTransaction];
[realm deleteObject:photoInDatabase];
[realm commitWriteTransaction];
}
}
}];
}
最佳答案
境界不安全。因此,只要您想写入Realm,它就必须与您创建对象的线程相同。
因此,在开始“addOperationWithBlock”操作之前,应该获取要访问的对象的唯一标识符,然后从该操作块中创建它。
因此,您可以执行以下三种选择之一:
- (void)didFavoriteButtonTapped:(FlickerPhotoCell *)photoCell {
NSIndexPath *indexPath = [self.collectionView indexPathForCell:photoCell];
FlickerPhoto *photo = [self.photos objectAtIndex:indexPath.item];
NSString *photoUniqueIdentifier = photo.id // Getting I'ts identifier before opening a new thread
photoCell.photoFavouriteButton.selected = !photo.isFavorited;
[self.opQueue addOperationWithBlock:^{
FlickerPhoto *photoToUpdate = [FlickerPhoto objectForPrimaryKey:photoUniqueIdentifier]; // Getting the object again from the data base, in the new thread contex
RLMRealm *realm = [RLMRealm defaultRealm];
[realm beginWriteTransaction];
photoToUpdate.isFavorited = !photoToUpdate.isFavorited;
[realm commitWriteTransaction];
//Saving in local database
NSPredicate *pred = [NSPredicate predicateWithFormat:@"photoURL == %@ AND isFavorited == YES", photoToUpdate.photoURL];
RLMResults *searchedPhotos = [FlickerPhoto objectsWithPredicate:pred];
FlickerPhoto *photoInDatabase = [searchedPhotos firstObject];
BOOL isPhotoExists = (photoInDatabase != nil);
if(photoToUpdate.isFavorited) {
if(!isPhotoExists) {
[realm transactionWithBlock:^{
[realm addObject:photoToUpdate];
}];
}
} else {
if(isPhotoExists) {
[realm beginWriteTransaction];
[realm deleteObject:photoInDatabase];
[realm commitWriteTransaction];
}
}
}];
关于ios - 在操作 block 中具有单独的Realm实例时,“从错误的线程访问了Realm”,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38671379/