PHAsset 在 PHAssetChangeRequest 完成后不反映变化
PHAsset doesn't reflect change after PHAssetChangeRequest completes
在文档中说:
After Photos runs the change block and calls your completion handler,
the asset’s state reflects the changes that you requested in the
block.
但是,在完成处理程序内部(以及完成处理程序之后),我的 PHAsset 没有改变。这是我用来更改收藏夹状态的代码,它是从 PHAsset 文档页面中提取的。
- (IBAction)touchedButtonFavoritePhoto:(id)sender {
AssetViewController *vc = self.viewControllers[0];
PHAsset *asset = vc.asset;
NSLog(@"touched fav 1: %d", asset.favorite);
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
// Create a change request from the asset to be modified.
PHAssetChangeRequest *request = [PHAssetChangeRequest changeRequestForAsset:asset];
// Set a property of the request to change the asset itself.
request.favorite = !asset.favorite;
NSLog(@"touched fav 2: %d", request.favorite);
} completionHandler:^(BOOL success, NSError *error) {
NSLog(@"Finished updating asset. %@: %d", (success ? @"Success." : error), asset.favorite);
NSLog(@"touched fav 3: %d", asset.favorite);
[self dispatchMainSynchronously:NO usingBlock:^{
[self updateFavoriteButtonForAsset:asset];
NSLog(@"touched fav 4: %d", asset.favorite);
}];
}];
[self dispatchAfter:2.0 usingBlock:^{
NSLog(@"touched fav 5: %d", asset.favorite);
}];
}
上面的-dispatchAfter:
和-dispatchMain:
函数只是调用gcd
函数在一定时间后异步执行block或者在主UI线程。
当我 运行 代码时,我看到它开始 1) Asset is Not Fav,然后 2) Request is Fav,3) Asset still Not Fav,4) Asset still Not Fav, 5) 资产仍然不受欢迎。
AppName[6155:3741600] startingPage.asset: <PHAsset: 0x1265f1b30> 4DFE1BBF-C16B-4150-8350-3FF1291B63B6/L0/001 mediaType=1/0, sourceType=1, (3264x2447), creationDate=2015-01-19 00:42:26 +0000, location=1, hidden=0, favorite=0
AppName[6155:3741600] touched fav 1: 0
AppName[6155:3741879] touched fav 2: 1
AppName[6155:3741879] Finished updating asset. Success.: 0
AppName[6155:3741879] touched fav 3: 0
AppName[6155:3741600] touched fav 4: 0
AppName[6155:3741600] touched fav 5: 0
我做错了什么?为什么我的资产 object 没有更新?
实际上,资产的 属性 已更改,但当 PHPhotoLibrary 未随更改对其进行修改时,它不会出现。
您可以尝试通过调用 PHAsset 的 fetchAssetsWithLocalIdentifiers: 方法来获取更新后的资产,以查看正确的结果。
这是照片框架中的错误。我相信这是 9.2 的回归。在所有以前的版本中,favorite
状态在完成块中如您预期和文档所述正确更新。
不过,我确实找到了解决方法。在 photoLibraryDidChange
中,请注意在修改 favorite
后会为该资产提供更改详细信息。您会注意到 objectAfterChanges
确实具有新的 favorite
状态。因此,不要在更改请求成功后立即更新您的 UI,而是在更改详细信息交付后更新它。例如:
//MARK: PHPhotoLibraryChangeObserver
func photoLibraryDidChange(changeInstance: PHChange) {
guard let photoAsset = self.asset,
let changeDetails = changeInstance.changeDetailsForObject(photoAsset)
else { return }
dispatch_async(dispatch_get_main_queue()) {
self.asset = changeDetails.objectAfterChanges as? PHAsset
//self.asset now has the proper favorite status
self.updateFavoriteButton()
if changeDetails.assetContentChanged {
self.updateImage()
}
}
}
在文档中说:
After Photos runs the change block and calls your completion handler, the asset’s state reflects the changes that you requested in the block.
但是,在完成处理程序内部(以及完成处理程序之后),我的 PHAsset 没有改变。这是我用来更改收藏夹状态的代码,它是从 PHAsset 文档页面中提取的。
- (IBAction)touchedButtonFavoritePhoto:(id)sender {
AssetViewController *vc = self.viewControllers[0];
PHAsset *asset = vc.asset;
NSLog(@"touched fav 1: %d", asset.favorite);
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
// Create a change request from the asset to be modified.
PHAssetChangeRequest *request = [PHAssetChangeRequest changeRequestForAsset:asset];
// Set a property of the request to change the asset itself.
request.favorite = !asset.favorite;
NSLog(@"touched fav 2: %d", request.favorite);
} completionHandler:^(BOOL success, NSError *error) {
NSLog(@"Finished updating asset. %@: %d", (success ? @"Success." : error), asset.favorite);
NSLog(@"touched fav 3: %d", asset.favorite);
[self dispatchMainSynchronously:NO usingBlock:^{
[self updateFavoriteButtonForAsset:asset];
NSLog(@"touched fav 4: %d", asset.favorite);
}];
}];
[self dispatchAfter:2.0 usingBlock:^{
NSLog(@"touched fav 5: %d", asset.favorite);
}];
}
上面的-dispatchAfter:
和-dispatchMain:
函数只是调用gcd
函数在一定时间后异步执行block或者在主UI线程。
当我 运行 代码时,我看到它开始 1) Asset is Not Fav,然后 2) Request is Fav,3) Asset still Not Fav,4) Asset still Not Fav, 5) 资产仍然不受欢迎。
AppName[6155:3741600] startingPage.asset: <PHAsset: 0x1265f1b30> 4DFE1BBF-C16B-4150-8350-3FF1291B63B6/L0/001 mediaType=1/0, sourceType=1, (3264x2447), creationDate=2015-01-19 00:42:26 +0000, location=1, hidden=0, favorite=0
AppName[6155:3741600] touched fav 1: 0
AppName[6155:3741879] touched fav 2: 1
AppName[6155:3741879] Finished updating asset. Success.: 0
AppName[6155:3741879] touched fav 3: 0
AppName[6155:3741600] touched fav 4: 0
AppName[6155:3741600] touched fav 5: 0
我做错了什么?为什么我的资产 object 没有更新?
实际上,资产的 属性 已更改,但当 PHPhotoLibrary 未随更改对其进行修改时,它不会出现。
您可以尝试通过调用 PHAsset 的 fetchAssetsWithLocalIdentifiers: 方法来获取更新后的资产,以查看正确的结果。
这是照片框架中的错误。我相信这是 9.2 的回归。在所有以前的版本中,favorite
状态在完成块中如您预期和文档所述正确更新。
不过,我确实找到了解决方法。在 photoLibraryDidChange
中,请注意在修改 favorite
后会为该资产提供更改详细信息。您会注意到 objectAfterChanges
确实具有新的 favorite
状态。因此,不要在更改请求成功后立即更新您的 UI,而是在更改详细信息交付后更新它。例如:
//MARK: PHPhotoLibraryChangeObserver
func photoLibraryDidChange(changeInstance: PHChange) {
guard let photoAsset = self.asset,
let changeDetails = changeInstance.changeDetailsForObject(photoAsset)
else { return }
dispatch_async(dispatch_get_main_queue()) {
self.asset = changeDetails.objectAfterChanges as? PHAsset
//self.asset now has the proper favorite status
self.updateFavoriteButton()
if changeDetails.assetContentChanged {
self.updateImage()
}
}
}