SDWebImage / SDWebImageSwiftUI

SwiftUI Image loading and Animation framework powered by SDWebImage
https://sdwebimage.github.io/SDWebImageSwiftUI
MIT License
2.16k stars 223 forks source link

Message from debugger: Terminated due to memory issue #122

Closed karenxpn closed 4 years ago

karenxpn commented 4 years ago

When loading approx. 100 images on scrolling fast app crashes( SwiftUI ) what is the reason and how it can be solved?

dreampiggy commented 4 years ago

Are you using WebImage or AnimatedImage ?

WebImage is just a SwiftUI.Image wrapper, which sounds really strange can cause crash.

karenxpn commented 4 years ago

I am just using WebImage. Removing it the app works fine.It loads all images but while scrolling the app crashes.( with 10-20 images its ok ) but with 50-100 or 200 images it is crashing. Maximum size of my images is 2MB.

And here is the error messages

[ServicesDaemonManager] interruptionHandler is called. -[FontServicesDaemonManager connection]_block_invoke

Message from debugger: Terminated due to memory issue

dreampiggy commented 4 years ago

Maximum size of my images is 2MB.

The Image Data Buffer side does not have any meaning for memory.

You need to calculate the Image Bitmap Size, the fomula is:

bytes usage = image pixels size * bytes per pixel(4 for most alpha images).

For example, 10000*10000 pixel need 381MB RAM.

See more about this in our wiki ? https://github.com/SDWebImage/SDWebImage/wiki/Common-Problems#reduce-image-memory-usage-by-resolution-and-channel

dreampiggy commented 4 years ago

Did you use WebImage in a List ? It should be re-used and the cache for memory should have a limit (See SDImageCacheConfig.maxMemorySize). Sounds strange that this cause OOM.

Any simple demo to reproduce this ? And your test environment (iOS version, Xcode version, SDWebImage && SDWebImageSwiftUI version) and sample URLs

karenxpn commented 4 years ago

Crash was fixed when I added options: .avoidDecodeImage but that cause an empty screen for about 1 second

karenxpn commented 4 years ago

struct SingleShop: View {

@ObservedObject var shopVM = ShopViewModel()
let shopModel: ShopListViewModel

init(shopModel: ShopListViewModel) {
    self.shopModel = shopModel
    self.shopVM.shopName = self.shopModel.name
    self.shopVM.getProducts()
}

var body: some View {

    ZStack {

        AllShopsBackground()

        VStack( spacing: 0) {

            ZStack {
                Image("singleShopFilter" )
                    .resizable()
                    .frame(width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height/9)

                VStack {
                    HStack {

                        TextDesign(text: shopModel.name, size: 13, font: "Montserrat-ExtraLight", color: Color.white)

                        Spacer()

                        TextDesign(text: "Հագուստ", size: 11, font: "Montserrat-ExtraLight", color: Color.white)
                            .padding([.top, .bottom], 8)
                            .padding([.horizontal], 12)
                            .background( self.shopVM.category == "Հագուստ" ? Color(UIColor(red: 90/255, green: 123/255, blue: 239/255, alpha: 1)) : Color(UIColor(red: 21/255, green: 23/255, blue: 41/255, alpha: 1)))
                            .cornerRadius(20)
                            .onTapGesture {
                                if self.shopVM.category == "Հագուստ" {
                                    self.shopVM.category = ""
                                } else {
                                    self.shopVM.category = "Հագուստ"
                                }
                        }

                        TextDesign(text: "Կոշիկ", size: 11, font: "Montserrat-ExtraLight", color: Color.white)
                            .padding([.top, .bottom], 8)
                            .padding([.horizontal], 12)
                            .background( self.shopVM.category == "Կոշիկ" ? Color(UIColor(red: 90/255, green: 123/255, blue: 239/255, alpha: 1)) : Color(UIColor(red: 21/255, green: 23/255, blue: 41/255, alpha: 1)))
                            .cornerRadius(20)
                            .onTapGesture {
                                if self.shopVM.category == "Կոշիկ" {
                                    self.shopVM.category = ""
                                } else {
                                    self.shopVM.category = "Կոշիկ"
                                }
                        }

                        TextDesign(text: "Աքսեսուարներ", size: 11, font: "Montserrat-ExtraLight", color: Color.white)
                            .padding([.top, .bottom], 8)
                            .padding([.horizontal], 12)
                            .background( self.shopVM.category == "Աքսեսուարներ" ? Color(UIColor(red: 90/255, green: 123/255, blue: 239/255, alpha: 1)) : Color(UIColor(red: 21/255, green: 23/255, blue: 41/255, alpha: 1)))
                        .lineLimit(1)
                            .cornerRadius(20)
                            .onTapGesture {
                                if self.shopVM.category == "Աքսեսուարներ" {
                                    self.shopVM.category = ""
                                } else {
                                    self.shopVM.category = "Աքսեսուարներ"
                                }
                        }
                    }

                    HStack {

                        TextDesign(text: self.shopVM.price == 0 ? "Գինը" : String(format: "%.0f", self.shopVM.price), size: 13, font: "Montserrat-ExtraLight", color: Color.white)
                            .padding([.top, .bottom], 6)
                            .padding([.trailing, .leading], 12)
                            .background(Color(UIColor(red: 90/255, green: 123/255, blue: 239/255, alpha: 1)))
                            .cornerRadius(20)

                        Spacer()

                        Slider(value: self.$shopVM.price, in: 0...400000, step: 1000)
                            .accentColor(Color(red: 20/255, green: 210/255, blue: 184/255, opacity: 1))
                            .frame(width: UIScreen.main.bounds.size.width * 0.5)
                    }

                }.padding([.leading, .trailing])
            }

            WaterfallGrid(self.shopVM.filter()) { product in
                SingleProduct(product: product)
            }
        }

        if self.shopVM.loading {
            Loading()
        }
    }.navigationBarTitleView( NavigationTitleView(), displayMode: .inline)
}

}

struct SingleProduct: View {

let product: ProductViewModel

var body: some View {
    NavigationLink(destination: SelectedProduct(product: product)) {
        if product.sale == 0 {

            VStack {

                ZStack {

                    VStack {

                        TextDesign(text: product.name, size: 13, font: "Montserrat-ExtraLight", color: Color.gray)
                            .lineLimit(1)

                        Divider().frame(width: UIScreen.main.bounds.size.width/2 - 40 )

                        WebImage(url: URL(string: product.images[0]), options: .avoidDecodeImage )
                            .resizable()
                            .scaledToFill()
                            .frame(width: UIScreen.main.bounds.size.width/2 - 40, height: UIScreen.main.bounds.size.height/7 )
                            .cornerRadius(10)

                        TextDesign(text: "\(product.price)դր.", size: 14, font: "Montserrat-ExtraLight", color: self.product.sale == 0 ? Color.gray : Color.red)
                            .padding(.trailing)
                            .offset(x: UIScreen.main.bounds.size.width/6.5)

                    }
                }
            }.padding([.top, .bottom], 6)
                .padding([.trailing, .leading], 10)
                .background(Color.white)
                .cornerRadius(15)

        } else {
            VStack {

                ZStack {

                    VStack {

                        TextDesign(text: product.name, size: 13, font: "Montserrat-ExtraLight", color: Color.gray)
                            .frame(width: UIScreen.main.bounds.size.width/2 - 40)
                            .lineLimit(1)

                        Divider().frame(width: UIScreen.main.bounds.size.width/2 - 40 )

                        WebImage(url: URL(string: product.images[0]), options: .avoidDecodeImage )
                            .resizable()
                            .scaledToFill()
                            .frame(width: UIScreen.main.bounds.size.width/2 - 40, height: UIScreen.main.bounds.size.height/7 )
                            .cornerRadius(10)

                        TextDesign(text: "\(product.price)դր.", size: 14, font: "Montserrat-ExtraLight", color: Color.red)
                            .padding(.trailing)
                            .offset(x: UIScreen.main.bounds.size.width/6.5)
                    }

                    Image("saleLabel")
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                        .frame(width: 60, height: 60)
                        .offset(x: UIScreen.main.bounds.size.width/6.5,
                                y: UIScreen.main.bounds.size.height == 667.0 ? -UIScreen.main.bounds.size.height/12 : -UIScreen.main.bounds.size.height/12.5)

                    Text( "\(product.sale)%")
                        .foregroundColor(Color.white)
                        .font(.system(size: 20))
                        .rotationEffect(.degrees(40))
                        .offset(x: UIScreen.main.bounds.size.width/5.5,
                                y: UIScreen.main.bounds.size.height == 667.0 ? -UIScreen.main.bounds.size.height/11 : -UIScreen.main.bounds.size.height/11.5)

                }

            }.padding([.top, .bottom], 6)
                .padding([.trailing, .leading], 10)
                .background(Color.white)
                .cornerRadius(15)
        }
    }.buttonStyle(PlainButtonStyle())
}

}

IOS 13.5.1 XCode 11.5

karenxpn commented 4 years ago

and now it uses about 3GB memory please help me solve this problem

dreampiggy commented 4 years ago

Closed ? Did this issue been solved ?

ykaito21 commented 3 years ago

@KALIMI Did you find any solution? I'm facing the similar issue

karenxpn commented 3 years ago

@KALIMI Did you find any solution? I'm facing the similar issue

Yeah. WebImage(url: URL(string: product.images[0]), context: [.imageThumbnailPixelSize : CGSize(width: 250, height: 250)])

ykaito21 commented 3 years ago

@KALIMI Thanks!