2017-12-10 8 views
1

SO 및 다른 기사 (아래 참조)에 대한 답변을 읽은 후에 애니메이션 배열에 여러 이미지를로드 할 때 메모리를 관리하는 가장 좋은 방법은 무엇입니까? ?UIImage - Swift 3.0을 사용할 때 메모리를 비우는 방법 캐시를 플러시하는 방법

  1. 하는 또 다른 애니메이션 (반복 씻어을 씻어을 애니메이션 캐시를 플러시 재생 후
  2. 을 애니메이션 어레이 (아래 코드 참조) 작성 및로드 : 여기

    http://www.alexcurylo.com/2009/01/13/imagenamed-is-evil/

    내 목표이다 애플이 https://forums.developer.apple.com/thread/17888

    을 상태로는

을 :) 얻을

UIImage(named: imageName)을 사용하면 이미지를 캐시하지만 내 경우에는 행에서 2-3 애니메이션을 재생 한 후 iOS가 응용 프로그램을 종료합니다 (OS가 메모리 부족 경고에 응답하지 않고 대신 응용 프로그램을 종료 함 - 아래 코드의 끝 부분을 참조하십시오)

나는 이미지를 캐시하지 않으려는 오히려 우리가 할 수 중 하나

  1. 메모리를 애니메이션이 완료 될 때마다 세척 한 다음 새 애니메이션을로드; 이것은을 방지하는 가장 좋은 방법이 될 수 있습니다처럼

    SO의 답변을 바탕으로
    // create the Animation Array for each animation 
    
    func createImageArray(total: Int, imagePrefix: String) -> [UIImage]{ 
        var imageArray: [UIImage] = [] 
        for imageCount in 0..<total { 
         let imageName = "\(imagePrefix)-\(imageCount).png" 
         let image = UIImage(named: imageName)! // here is where we need to address memory and not cache the images 
    
         //let image = UIImage(contentsOfFile: imageName)! // maybe this? 
    
         imageArray.append(image) 
        } 
        return imageArray 
    } 
    
    
    // here we set the animate function values 
    
    func animate(imageView: UIImageView, images: [UIImage]){ 
        imageView.animationImages = images 
        imageView.animationDuration = 1.5 
        imageView.animationRepeatCount = 1 
        imageView.startAnimating() 
    } 
    
    // Here we call the animate function 
    
    animation1 = createImageArray(total: 28, imagePrefix: "ImageSet1") 
    animation2 = createImageArray(total: 53, imagePrefix: "ImageSet2") 
    animation3 = createImageArray(total: 25, imagePrefix: "ImageSet3") 
    
    func showAnimation() { 
        UIView.animate(withDuration: 1, animations: { 
         animate(imageView: self.animationView, images: self.animation1) 
    
         }, completion: { (true) in 
    
         //self.animationView.image = nil // Maybe we try the following? 
         //self.animationView.removeFromSuperview() 
         //self.animationView = nil 
    
         }) 
        } 
    

    , 보이는 : 새로운 장면 여기

에 대한 사용자 이동 내 코드 인 경우 또는

  • 메모리를 플러시 의 이미지는 캐시되는,하지만 내 코드에서 작동하지 않는 것 : 나는이 시도했다

    let image = UIImage(contentsOfFile: imageName)! 
    

    하지만이 중 하나가 작동하지 않는 것 :

    func applicationDidReceiveMemoryWarning(application: UIApplication) { 
        NSURLCache.sharedURLCache().removeAllCachedResponses() 
    } 
    

    는 또한 완료 블록의 다음 문서 (removeFromSuperview)를 시도하지만이 중 하나 (위의 내 코드 참조) 작동시킬 수 없습니다 :

    https://www.hackingwithswift.com/example-code/uikit/how-to-animate-views-using-animatewithduration

    새로운 코드 :

    // create the Animation Array for each animation 
    
    func createImageArray(total: Int, imagePrefix: String) -> [UIImage]{ 
        var imageArray: [UIImage] = [] 
        for imageCount in 0..<total { 
         let imageName = "\(imagePrefix)-\(imageCount).png" 
         //let image = UIImage(named: imageName)! // replaced with your code below 
    
        if let imagePath = Bundle.mainBundle.path(forResource: "ImageSet1" ofType: "png"), 
        let image = UIImage(contentsOfFile: imagePath) { 
         //Your image has been loaded } 
    
         imageArray.append(image) 
        } 
        return imageArray } 
    
  • +0

    는 말 : "하지만 내 코드에서 작동하지 않는 것 같습니다." 무슨 소리 야? 아직도 해산 당했어? 애니메이션을 볼 수 없습니까? –

    +0

    안녕하세요 @ AndreaMugnaini - 나는 다양한 기사에서 제안 된 답변을 시도했지만 (예 : //로 표시된 주석 참조) 예, 아직 해지 중입니다. 애니메이션은 완벽하게 작동하지만 추가 애니메이션을 하나씩 추가하면 전체 메모리 사용량이 늘어납니다. 나는 단순히 self.animationView.removeFromSuperview()를 사용하여 애니메이션을 플러시 할 수 있다고 생각했지만, 어느 쪽도 작동하지 않는 것 같습니다 (메모리는 동일하게 유지됩니다). 희망이 –

    +0

    당신의 png 파일 크기를 확인할 수 있습니다 명확히하는 데 도움이됩니까? –

    답변

    2

    아주 간단합니다. UIImage(named:)은 이미지를 캐시하고 UIImage(contentsOfFile:)은 캐시하지 않습니다.

    이미지를 캐시하지 않으려면 대신 UIImage(contentsOfFile:)을 사용하십시오. 코드를 게시 할 수 없다면 코드를 게시하면 디버그하는 데 도움이됩니다.

    UIImage(contentsOfFile:)은 앱 번들의 파일을 찾지 않습니다. 이미지 파일의 전체 경로가 필요합니다.당신은 파일의 경로를 찾을 Bundle 방법을 사용하고 UIImage(contentsOfFile:)에 해당 경로를 통과해야합니다 귀하의 코드는 이미지의 배열에 3 개 애니메이션에 대한 모든 이미지를로드하고 해제되지 않습니다

    if let imagePath = Bundle.mainBundle.path(forResource: "ImageSet1" ofType: "png"), 
        let image = UIImage(contentsOfFile: imagePath) { 
        //Your image has been loaded 
    } 
    

    , 그래서 시스템이 그 이미지들을 캐시한다는 사실은 꽤 무의미한 것처럼 보입니다. 낮은 메모리 조건에서 시스템은 캐시 된 이미지 복사본을 플러시해야하지만 코드는 여전히 배열의 모든 이미지를 보유하므로 메모리가 해제되지 않습니다. 내게는 시스템의 이미지 캐싱이 아니라 메모리 문제를 일으키는 코드가있는 것처럼 보입니다.

    코드는 다음과 같습니다

    func createImageArray(total: Int, imagePrefix: String) -> [UIImage]{ 
        var imageArray: [UIImage] = [] 
        for imageCount in 0..<total { 
         let imageName = "\(imagePrefix)-\(imageCount)" 
         if let imagePath = Bundle.main.path(forResource: imageName, 
          ofType: "png"), 
          let image = UIImage(contentsOfFile: imagePath) { 
           imageArray.append(image) 
         } 
        } 
        return imageArray 
    } 
    
    +0

    아니요. 나는 너를 해결하기 위해 그걸 맡길거야. 그래서 대답 복사 - 붙여 넣기 준비 코드를 제공하지 않습니다. 내 대답을 코드에 적용하면 더 많은 것을 배울 수 있습니다. –

    +0

    메모리를 비우려면 이미지 배열을 해제해야합니다. 배열은 이미지에 대한 강력한 참조를 보유하고 있기 때문에 메모리 사용 공간이 줄어들지 않습니다. –

    +0

    질문을 편집하여 마지막에 새로운 'UIImage (contentsOfFile :)'변경 사항을 표시하십시오. 설명하는 오류는 코드가 값이 아닌 클로저를 반환하도록 작성된 것처럼 들립니다. –