4

ドキュメントには次のように書かれています。

Photos が変更ブロックを実行して完了ハンドラーを呼び出すと、ブロックで要求した変更がアセットの状態に反映されます。

ただし、完了ハンドラー内 (および完了ハンドラーの後) では、私の 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:および関数は、関数を呼び出して一定時間後にブロックを非同期で実行するか、メイン UI スレッドでブロックを実行する-dispatchMain:便利な関数です。gcd

コードを実行すると、1) Asset is Not Fav、2) Request is Fav、3) Asset is still Not Fav、4) Asset is still Not Fav、5) Asset is still Not Fav で始まることがわかります。

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

私は何を間違っていますか?アセット オブジェクトが更新されないのはなぜですか?

4

2 に答える 2

2

これは Photos フレームワークのバグです。9.2 のリグレッションだと思います。以前のすべてのリリースfavoriteでは、完了ブロックでステータスが適切に更新されており、ドキュメントに記載されているとおりです。

しかし、私は回避策を見つけました。ではphotoLibraryDidChange、 の変更後にこのアセットの変更の詳細が提供されることに注意してくださいfavoriteobjectAfterChangesが新しい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()
        }
    }
}
于 2016-01-09T03:11:52.970 に答える