AVAsset loadValuesAsynchronouslyForKeys:completionHandler 从不执行
Posted
技术标签:
【中文标题】AVAsset loadValuesAsynchronouslyForKeys:completionHandler 从不执行【英文标题】:AVAsset loadValuesAsynchronouslyForKeys:completionHandler never executes 【发布时间】:2018-02-10 05:27:36 【问题描述】:这个问题已经在这里问了好几次了,但我仍然没有在任何地方看到任何答案。这已经杀死了我几个小时,我希望在这里得到一些帮助。我有以下代码:
NSURL *url = [NSURL URLWithString:sourceVideoName];
NSDictionary *options = @ AVURLAssetPreferPreciseDurationAndTimingKey: @YES ;
PHFetchResult *ph_fetch = [PHAsset fetchAssetsWithALAssetURLs:@[url] options:nil];
PHAsset *ph_asset = [ph_fetch firstObject];
RCTLogInfo(@"Now we have PHAsset:\n%@", ph_asset);
[[PHImageManager defaultManager] requestAVAssetForVideo:ph_asset options:options resultHandler:^(AVAsset * _Nullable asset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info)
RCTLogInfo(@"Now we have AVAsset:\n%@", asset);
NSError *error = nil;
AVKeyValueStatus tracksStatus = [asset statusOfValueForKey:@"tracks" error:&error];
switch (tracksStatus)
case AVKeyValueStatusCancelled:
[self log:@"Early Tracks Canceled"];
break;
case AVKeyValueStatusLoading:
[self log:@"Early Tracks Loading"];
break;
case AVKeyValueStatusLoaded:
[self log:@"Early Tracks Loaded"];
break;
case AVKeyValueStatusFailed:
[self log:@"Early Tracks Failed"];
break;
case AVKeyValueStatusUnknown:
[self log:@"Early Tracks Unknown"];
break;
[asset loadValuesAsynchronouslyForKeys:@[@"tracks", @"duration"] completionHandler:^()
RCTLogInfo(@"We finally have a track callback???");
];
];
当然,我们从来没有真正执行过最终的回调。我不知道为什么,也不知道如何解决它。
【问题讨论】:
这可能是 ARC 问题。 【参考方案1】:对我的问题的评论让我深入了解了答案。基本版本是,在回调执行之前,asset
似乎已从内存中释放。
ARC 为属性提供了更强的内存保留,因此可以通过在标头中添加接口定义来实现:
@property AVAsset *asset;
@property PHAsset *photoAsset;
并将上述问题中的代码转换为:
NSURL *url = [NSURL URLWithString:sourceVideoName];
NSDictionary *options = @ AVURLAssetPreferPreciseDurationAndTimingKey: @YES ;
PHFetchResult *ph_fetch = [PHAsset fetchAssetsWithALAssetURLs:@[url] options:nil];
[self setPhotoAsset:[ph_fetch firstObject]];
RCTLogInfo(@"Now we have instance PHAsset:\n%@", [self photoAsset]);
[[PHImageManager defaultManager] requestAVAssetForVideo:[self photoAsset] options:nil resultHandler:^(AVAsset * _Nullable localAsset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info)
RCTLogInfo(@"Now we have local AVAsset:\n%@", localAsset);
[self setAsset:localAsset];
RCTLogInfo(@"Now we have instance AVAsset:\n%@", [self asset ]);
NSError *error = nil;
AVKeyValueStatus tracksStatus = [[self asset] statusOfValueForKey:@"tracks" error:&error];
switch (tracksStatus)
case AVKeyValueStatusCancelled:
[self log:@"Early Tracks Canceled"];
break;
case AVKeyValueStatusLoading:
[self log:@"Early Tracks Loading"];
break;
case AVKeyValueStatusLoaded:
[self log:@"Early Tracks Loaded"];
break;
case AVKeyValueStatusFailed:
[self log:@"Early Tracks Failed"];
break;
case AVKeyValueStatusUnknown:
[self log:@"Early Tracks Unknown"];
break;
[[self asset] loadValuesAsynchronouslyForKeys:@[@"tracks", @"duration"] completionHandler:^()
RCTLogInfo(@"We finally have a track callback!!!");
];
];
【讨论】:
以上是关于AVAsset loadValuesAsynchronouslyForKeys:completionHandler 从不执行的主要内容,如果未能解决你的问题,请参考以下文章
AVAsset "tracksWithMediaType" 返回一个空数组