Hoşgeldin. Soru sormak veya cevaplamak için hemen üye ol.

Memory Warning Hatalarını Nasıl Kontrol Edip Düzelteceğiz ?

0 oy
92 kez görüntülendi
22, Mayıs, 2015 ios development kategorisinde burhanaksendir tarafından soruldu
22, Mayıs, 2015 burhanaksendir tarafından düzenlendi
Merhaba,
uygulamalarımızda resim, video vs kullandığımızda oluşan memory warning hatalarının sebeplerini incelemek, tespit etmek ve düzeltmek için neler yapmalıyız ? Bu konuda tecrübelerinizi paylaşabilir misiniz ?

Ben projeme embed ettiğim resimleri görüntülerken veya video oynattırırken ara sıra memory warning hataları alıyorum. Ancak  bu hataları nasıl ortadan kaldıracağım konusunda tecrübesizim ve mümkünse bir örnekle yardımınızı rica ediyorum. Çünkü sizin anlatımınız gerçekten çok harika.

Teşekkürler.

1 cevap

+1 oy
22, Mayıs, 2015 yasin tarafından cevaplandı
22, Mayıs, 2015 burhanaksendir tarafından seçilmiş
 
En İyi Cevap

memory handling oldukça sıkıntılı bir mevzu olabilir kim zaman, uygulamanızı yazmaya başlamadan önce uygulamanızın ilgili cihazlar ve ios sürümlerinde nasıl bir performansla çalışabileceğini iyi düşünmeniz gerekir. Özellike grafik işleme durumunda memoryl'le ilgili kesin problem yaşarsınız.
aslında ARC birçok şeyi bizim adımıza hallediyor ama siz doğru bir planlama yaparsanız tabi.
xcode içerisinden uygulamanızın performansını ölçmek için kullanabileceğiniz araçlar bulunmaktadır.
bu araçlara xCode menüsü altında yer alan open developer tool seçeneği altındaki instruments seçeneğinden ulaşabilirsiniz.
bu toolar arasında yer alan leaks ve allocations uygulamaları ile cihazınız üzerinde çalıştırdığınız uygulamanıza ait realtime performansı tespit edebilirsiniz.

memory handling konusunda nasıl bir örnek verebilirim bilmiyorum ama.
ownership hiyerarşisini iyi kurun, gereksiz strong reference'lardan kaçının
mümkün olduğunca weak referance kullanın.

imaj dosyalarıyla ilgili olarak en önemli şey,
UIImage(named:"myImage.jpg") defalarca kullanmayın, eğer aynı imajı birden fazla yerde kullanıyor veya ileride tekrar çağırıyorsanız muhakkak bir caching mekanizması kurun.

muhakkak suretle ARC dokümantasyonunu inceleyin.

22, Mayıs, 2015 burhanaksendir tarafından yorumlandı
Çok teşekkür ederim. instruments temel düzeyde memory analizi ile ilgili Türkçe bir kaynak var mı acaba bildiğiniz ?

UIViewController içerisinde StoryBoard'ta bir collectionview oluşturdum ve içerisindeki cell'lere  projeme embed ettiğim birer imaj ekledim. Toplam 15 resim oldu. Galeri mantığı gibi. Bu resimleri görüntülemek için yeni bir ViewController oluşturdum ve içine bir ScrollView ekleyip onun da içerisine bir UIImageView ekledim.  Pan ve Zoom yapabilsinler diye...

Resimleri dediğiniz gibi UIImage(name: "myImage.jpg) şeklinde tanımlamıştım.  Embed ettiğim bu galeride fotolar için bir caching nasıl oluşturabilirim ? Yoksa netten çekince mi geçerli bu söylediğiniz ?

Daha sonra left -right swipe gesture ile resimler arasında gezinti yaptırıyorum. İşte bu esnada memory kullanımı artmaya başlıyor ve  receive memory warningi alıyorum ve öylece kalıyorum :)
22, Mayıs, 2015 yasin tarafından yorumlandı
türkçe kaynak varmı ben de bilemiyorum.

image caching için de şöyle birşey yapabilirsiniz.


ImageCaller adında bir UIImage subclass'ı oluşturun;




import Foundation
import UIKit

var imageCache = Dictionary<String,UIImage>()

class ImageCaller:UIImage {
    
    
    class func imageWithName(named:String) -> UIImage! {
        var returningImage:UIImage! = nil
        if let imageFromCache:UIImage = imageCache[named] {
            returningImage = imageFromCache
            println("image called from cache")
        } else {
            if let createdImage:UIImage = UIImage(named: named) {
                imageCache[named] = createdImage
                returningImage = createdImage
                println("image created and append to the cache")
            }
        }
        return returningImage
    }
    
    
    class func clearCache() {
        println("cache cleared for \(imageCache.count) image")
        imageCache.removeAll(keepCapacity: false)
    }
    
}




ve bir imajı çağırırken UIImage(name: "myImage.jpg)  yerine bunu kullanın:

ImageCaller.imageWithName("myImage.jpg")


viewController içerisinde yer alan didReceiveMemoryWarning metodu içerisine de

ImageCaller.clearCache()

ekleyin. Bu sayede memory şiştiğinde, imageCaller içerisinde bir array'da tutuğunuz imajları silerek memoy'de yer kazanmış olursunuz.
22, Mayıs, 2015 burhanaksendir tarafından yorumlandı
Gerçekten hayat kurtaran eşsiz bilgiler. Çok teşekkür ederim.
Storyboard üzerinde oluşturduğum ve tanımladığım imageView'ler için de  image tanımlama kısmını, ilgili ViewController'deki viewdidload methodu içinde ImageCaller.imageWithName ile tanımlamam doğru olur mu ?  

Tekrar teşekkürler.
22, Mayıs, 2015 yasin tarafından yorumlandı
olur tabiki. bir problem yaratmaz.
ama daha önce dediğimi unutmayın,
eğer bir nesneyi bir kere yarattıktan sonra eğer kullanılmıyorsa tamamen kaldırın.
mesela daha önceki yorumunuzda scrollView içerisine imageView'ler eklediğinizi
ve swipe ederek bu imageView'lar arasında gezindiğinizi bu esnada memory kullanımının arttığından bahsetmiştiniz.
aslında bu da sıkıntı yaratacak bir mevzu.
kullanacağınız imageView sayısı değişken mi bilemiyorum ama misal 100 tane imageView'i arka arkaya scrollView'in içerisine atıp swipe'la aralarında gezinmek başlı başına bir hatadır.

bunun için reusable bir yapı kurmanız daha iyi olacaktır. iki tane imageView'la bu iş kotarılabilirsiniz, ama tabi o zaman custom bir scrollView yaratmanız ve her swipe'da bu iki imageView'in sıralamasını ve içeriğindeki imajları değiştirmeniz gerekirki bu da hatrı sayılır bir iş yükü demek anlamına geliyor. ama maalesef böylesi kısıtlı donanımlarda mümkün olan her kaynaktan tasarruf etmelisiniz.
22, Mayıs, 2015 burhanaksendir tarafından yorumlandı
Çok teşekkür ederim. bahsettiğiniz şekilde bir scrollview yapısı kurmaya çalışacağım.

Genel manada değişken tanımlarken örneğin :
var myArray = NSMutableArray() şeklinde mi yoksa
weak var myArray = NSMutableArray()  şeklinde mi tanımlamam daha doğru olur ? Bu kısmı da tam idrak edemiyorum.

 Bunun da memory ile bağlantısı var sanıyorum, yanılıyor muyum ?  Ben bu tanımladığım array'i başka  bir viewe geçerken işim bittiğinde viewDidDisappear içerisinde nil'e eşitliyorum. myArray.removeAllObjects() şeklinde...
...