2017-01-23 11 views
0

그러나충돌 나는 카메라 롤에서 일부 동영상로드 <code>PHCachingImageManager().requestAVAsset</code>을 사용하고

override func viewDidLoad() { 
    super.viewDidLoad() 
    print("SEGUE SUCCESSFUL") 
    view.backgroundColor = .black 
    avPlayerLayer = AVPlayerLayer(player: avPlayer) 
    view.layer.insertSublayer(avPlayerLayer, at: 0) 

    var asset2:AVAsset? = nil 

    PHCachingImageManager().requestAVAsset(forVideo: (vidLocation?[videoSender]!)!, options: nil, resultHandler: {(asset: AVAsset?, audioMix: AVAudioMix?, info: [AnyHashable : Any]?) in 
     asset2 = asset! as AVAsset 
     }) 


    let playerItem = AVPlayerItem(asset: asset2!) 
    avPlayer.replaceCurrentItem(with: playerItem) 
} 

을 나는 그것이 PHCachingImageManager().requestAVAsset 줄에서 일시 정지와 쇼 프로그램을 실행하면

스레드 1 : EXC_BREAKPOINT은

012 (녹색으로 강조 표시)

무슨 일이 일어나고 있는지 잘 모르겠습니다. 설명서에서 이해할 수있는 부분을 찾을 수 없습니다. 이 문제를 어떻게 해결할 수 있습니까?

+0

호출에 대한 매개 변수 중 하나에 두 개의 강제 실행 취소 연산이 있습니다 ('(vidLocation? [videoSender]!)!)). 아마도 그들 중 적어도 하나는 무효 일 것입니다. 또한 크래시와 무관한데,'requestAVAsset'에 대한 완료 핸들러는 비동기 적이므로'playerItem'을 설정 한 코드를 * 수행 한 후에'asset2'는 항상 nil이됩니다. 당신이 그것을 사용하려고 할 때. – rickster

답변

0

이 작업을 수행하기 위해 여기에서 수행하려는 몇 가지 사항이 있습니다.

  1. 살아 남을 개체에 PHCachingImageManager을 속성으로 캐시해야합니다. 어딘가에 저장하지 않고 만들면 ARC 규칙에 따라 규칙이 삭제됩니다. 아래의 코드에서 저는 게으른 var를 사용하지만, 그렇게하는 유일한 방법은 아닙니다.
  2. 코드에서 모든 적용되지 않은 unwrap 된 옵션 !을 제거해야합니다. guard let ... 또는 if let ... 패턴을 사용하면 입력하는 것처럼 느껴질 수 있지만 결국 많은 시간과 좌절을 줄일 수 있습니다. !을 "CRASH HERE!"라고 표시된 위험 신호로 생각하십시오.
  3. 완료 블록 resultHandler에서 AVPlayerItem을 설정해야합니다. requestAVAsset은 비동기 적이므로 주 스레드를 차단하지는 않지만 비싼 자산을 검색하는 작업은 수행하지 않습니다. 기본적으로 requestAVAsset을 호출하자마자 별도의 스레드가 작동하여 주 스레드가 viewDidLoad 메서드의 나머지 코드에서 작업을 계속합니다. AVAsset을 성공적으로 검색하면 원래 제공 한 코드 블록 (메인 스레드)을 다시 호출하므로 처리를 계속할 수 있습니다.

    lazy var imageManager = { 
        return PHCachingImageManager() 
    }() 
    
    override func viewDidLoad() { 
        super.viewDidLoad() 
        print("SEGUE SUCCESSFUL") 
        view.backgroundColor = .black 
        avPlayerLayer = AVPlayerLayer(player: avPlayer) 
        view.layer.insertSublayer(avPlayerLayer, at: 0) 
    
        var asset2:AVAsset? = nil 
    guard let phAsset = vidLocation?[videoSender] else { return } //No video 
    
    imageManager.requestAVAsset(forVideo: phAsset, options: nil, resultHandler: {(asset: AVAsset?, audioMix: AVAudioMix?, info: [AnyHashable : Any]?) in 
        if let avAsset = asset { 
         self.play(asset: avAsset) 
        } 
    }) 
    
    func play(asset: AVAsset) { 
        let playerItem = AVPlayerItem(asset: asset) 
        avPlayer.replaceCurrentItem(with: playerItem) 
    } 
    

    아무것도 불분명 알려줘 :

는 여기에 내가 제안하고있어 변경 사항을 반영하기 위해 다시 작성 코드입니다.

+1

완벽한 -이 일을했습니다. 코드에 대한 유일한 편집은 다음과 같습니다 :'guard let phAsset = vidLocation? [videoSender] else {return // No video}'나는 이것을 다음과 같이 변경해야했습니다 :'guard는 phAsset = vidLocation? [videoSender] else { return} // 비디오 없음'else의 닫는 괄호는 주석 처리되지 않습니다. – ZiEiTiA

+0

아 물론. 일치하도록 답변을 업데이트하겠습니다. –