Сбои приложения, и я не могу найти причину - PullRequest
0 голосов
/ 27 октября 2019

Я работал над разработкой приложения. Я также реализовал Crashlytics в приложении. Во время тестирования на устройстве это вызвало странный сбой, который я не могу устранить. Здесь я публикую журнал сбоев

Crashed: com.apple.main-thread
0  Business Card                  0x104c951ec specialized closure #1 in PostVC.tableView(_:cellForRowAt:) (<compiler-generated>)
1  Business Card                  0x104b22738 thunk for @escaping @callee_guaranteed (@guaranteed FIRDataSnapshot) -> () (<compiler-generated>)
2  Business Card                  0x104d39c0c __71-[FIRDatabaseQuery observeSingleEventOfType:withBlock:withCancelBlock:]_block_invoke + 479 (FIRDatabaseQuery.m:479)
3  Business Card                  0x104d39e74 __92-[FIRDatabaseQuery observeSingleEventOfType:andPreviousSiblingKeyWithBlock:withCancelBlock:]_block_invoke + 502 (FIRDatabaseQuery.m:502)
4  Business Card                  0x104d26724 __43-[FChildEventRegistration fireEvent:queue:]_block_invoke.53 + 74 (FChildEventRegistration.m:74)
5  libdispatch.dylib              0x1a752fbb0 _dispatch_call_block_and_release + 32
6  libdispatch.dylib              0x1a753100c _dispatch_client_callout + 20
7  libdispatch.dylib              0x1a753ccd8 _dispatch_main_queue_callback_4CF + 968
8  CoreFoundation                 0x1a7804e20 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 16
9  CoreFoundation                 0x1a77ffb7c __CFRunLoopRun + 1980
10 CoreFoundation                 0x1a77ff098 CFRunLoopRunSpecific + 480
11 GraphicsServices               0x1b1969534 GSEventRunModal + 108
12 UIKitCore                      0x1ab91f7ac UIApplicationMain + 1940
13 Business Card                  0x104afa3fc main + 18 (AppDelegate.swift:18)
14 libdyld.dylib                  0x1a767ef30 start + 4

И вот код, в котором говорится, что он разбился для файла PostVc.swift.

//
//  PostVC.swift
//  Business Card
//
//  Created by Elev 8 Valley on 1/10/18.
//  Copyright © 2018 elev8valley. All rights reserved.
//

import Foundation
import UIKit
import Firebase

class PostVC: UIViewController{
    @IBOutlet weak var userImage: UIImageView!
    @IBOutlet weak var nameField: UILabel!
    @IBOutlet weak var postField: UITextView!
    @IBOutlet weak var notificationsTable: UITableView!

    var window: UIWindow?
    var postId: String?
    var notifications  = [MyNotification](){
        didSet{

        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = .white
        FirebaseConnection.Connection().notificaionsListerner = self
       // FirebaseConnection.Connection().getNotificationList()
        UINavigationBar.appearance().tintColor = UIColor.white
        //self.navigationController?.navigationBar.barTintColor = darkGrayBackgroundColor
        //self.navigationController?.navigationBar.tintColor = UIColor.white
        // Do any additional setup after loading the view.
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        userImage.layer.masksToBounds = true
        userImage.layer.cornerRadius = userImage.frame.width / 2
        userImage.layer.borderColor = UIColor.white.cgColor
        userImage.layer.borderWidth = 2


        retrieveUserProfile()
    }

    func retrieveUserProfile(){
        if let pid = self.postId{
            var path = "Posts/\(pid)"
            self.window = Popup.show(vc: self)
            let ref = Database.database().reference(withPath: path)
            ref.observeSingleEvent(of: .value, with: { (snapshot) in
                if let w = self.window{
                    DispatchQueue.main.async {
                        Popup.hide(alertWindow: w)
                    }
                }
                if snapshot.exists(){
                    if let dic = snapshot.value as? NSDictionary{
                        DispatchQueue.main.async {
                            self.postField.text = dic["postContent"] as? String
                            //self.nameField.text = dic["postCreatorName"] as? String
                            if let postCreatorId = dic["postCreatorId"] as? String{
                                var path = "Profile"
                                path = "\(path)/\(postCreatorId).png"
                                let ref = Storage.storage().reference(withPath: path)
                                downloadImage(ref: ref, imageView: self.userImage)
                                self.downloadUserDetails(id: postCreatorId)
                            }

                            var not = [MyNotification]()
                            for p in self.notifications{
                                if let pid = p.postId, let id = self.postId{
                                    if pid == id{
                                        not.append(p)
                                    }
                                }
                            }
                            self.notifications = not
                            self.notificationsTable.reloadData()
                        }
                    }
                }
                else{
                    MessageBox.showSnackbar(message: "Post deleted")
                    self.navigationController?.popToRootViewController(animated: true)
                    print("No snapshot")
                }
            })
        }
    }
    private func downloadUserDetails(id: String){
        let path = "users/\(id)"
        Database.database().reference(withPath: path).observeSingleEvent(of: .value, with: {
            (snapshot) in
            if let dic = snapshot.value as? NSDictionary{
                DispatchQueue.main.async {
                    if let name = dic["name"] as? String{
                        self.nameField.text = name
                    }
                }
            }
        })
    }


}



extension PostVC : UITableViewDelegate, UITableViewDataSource{

    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let header = UIView()
        header.backgroundColor = UIColor.clear
        return header
    }

    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 5
    }


    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        if notifications[indexPath.section].notificationType == NotificationType.Request{
            return 120
        }
        return 100
    }
    func numberOfSections(in tableView: UITableView) -> Int {
        return notifications.count
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let not = notifications[indexPath.section]


        var gencell = tableView.dequeueReusableCell(withIdentifier: "notificationCell", for: indexPath)

        if not.notificationType == NotificationType.Comment || not.notificationType == NotificationType.Like{
            var cell = gencell as! RequestNotificationCell

            if let name = not.fromName, !name.isEmpty{
                cell.customView?.nameLabel.text = not.fromName
                cell.customView?.descriptionLabel.text = not.message
                cell.customView?.timeLabel.text = not.time?.timeAgoDisplay()
            }
            else{
                if let id = not.from.id{
                    Database.database().reference(withPath: "users/\(id)").observeSingleEvent(of: .value, with: { (snapshot) in
                        if let dic = snapshot.value as? NSDictionary{
                            let user = CircleUser(dic: dic)
                            if let name = dic.value(forKey: "name") as? String{
                                self.notifications[indexPath.section].fromName = name
                                cell.customView?.nameLabel.text = not.fromName
                                cell.customView?.descriptionLabel.text = not.message
                                cell.customView?.timeLabel.text = not.time?.timeAgoDisplay()
                            }
                        }
                    })
                }
            }

            var path = "Profile"
            if let uid = not.from.id{
                path = "\(path)/\(uid).png"

            }
            let ref = Storage.storage().reference(withPath: path)
            let placeHolder = #imageLiteral(resourceName: "boy")
            //let task = cell.customView?.image.sd_setImage(with: ref, placeholderImage: nil)
            cell.customView?.image.sd_setImage(with: ref, placeholderImage: #imageLiteral(resourceName: "client"), completion: { (image, error, cache, ref) in
                if let image = image{

                }
            })


            cell.customView?.addBtn.isHidden = true
            cell.customView?.rejectBtn.isHidden = true
            return cell

        }

        return gencell

    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let not = self.notifications[indexPath.section]

    }
}





extension PostVC : NotificationListener{
    func notificationsRetrieved(notifications: [MyNotification]) {
        self.notifications = notifications
        if notifications.count > 0{
            //reload data
            notificationsTable.reloadData()
        }
        else{
            MessageBox.Show(message: "No Notifications", title: "Empty", view: self)
        }
    }
}

Я искал поток в stackoverflowчто это утечка памяти, но я не знаю, где именно происходит эта утечка памяти.

Вот видео о том, как он разбился. Крах !

1 Ответ

1 голос
/ 29 октября 2019

Первое, что нужно сделать, это выяснить, что протекает. Для этого вы можете установить точки останова и использовать график отладочной памяти, чтобы увидеть, что находится в памяти и что к ней относится. График памяти также поместит индикаторы против протекающих экземпляров, чтобы помочь вам разобраться в этом.

Как только вы поймете, что происходит, вы можете посмотреть на точки в коде, где он создан. и упомянул, чтобы выяснить, почему это происходит.

Аналитика аварийных ситуаций и журналы сбоев, подобные тому, который вы опубликовали, хороши для определения, когда что-то сломалось. Но такие вещи, как утечки памяти, часто находятся где-то еще в коде и редко иллюстрируются в отчете о сбое.

Наконец, по моему опыту, сбои обычно не вызваны утечками памяти, за исключением случаев, когда что-то просочилось и некоторые его внутренние ссылки были исключены. Затем, если он вызван уведомлением или другим событием, он может завершиться с неожиданным нулем. Часто утечки памяти либо просто потребляют память, либо вызывают странное поведение из-за того, что несколько объектов конкурируют, чтобы сделать что-то, где должен работать только один.

...