Подтвердить что ты не робот

Firebase observSingleEvent остается в памяти

Мое приложение использует firebase observSingleEventOfType довольно честно, и я понял, что память моего приложения увеличивается со временем. Я прокомментировал весь мой код, кроме кнопки тестирования, которая вызывает следующую функцию.

func loadPostsTest() {
    FIRDatabase.database().reference().child("posts").observeSingleEventOfType(.Value, withBlock: { (snapshot: FIRDataSnapshot) in
        print(snapshot.value)
    })
}

Когда программа запускается, я быстро нажимаю тестовую кнопку примерно 2,3 раза в секунду и наблюдаю график памяти, как показано ниже. Память поднимается и не возвращается после запроса. Из-за этого проблема в моем приложении довольно справедлива, так как из-за этого память моего приложения будет расти с 70 мб до 150 + мб. Любая причина для этого?

Обратите внимание, что в течение короткой пятисекундной остановки я остановился, чтобы убедиться, что все "снимки" распечатаны.

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

образ памяти

------- UPDATE ----------

Чтобы еще раз подтвердить эту проблему, я создал совершенно новый проект, в котором ничего нет, кроме импорта firebase, кнопки в панели рассказов со следующим кодом и симуляции на моих 6-х (симуляция на симуляторе, похоже, не имеет этой проблемы). Образ ниже доказывает, что здесь есть что-то рыбное, где моя память переместилась с 11.1mb до 17.3mb с 303 запросами в течение минуты или около того.

memoryleak2

import UIKit
import Firebase

class ViewController: UIViewController {

var count: Int = 0

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
}

@IBAction func testBtnPressed(sender: AnyObject) {
    FIRDatabase.database().reference().child("posts").observeSingleEventOfType(.Value, withBlock: {[weak self] (snapshot: FIRDataSnapshot) in
        print(self?.count)
        self?.count += 1
    })
}
4b9b3361

Ответ 1

Вероятно, это происходит только потому, что вы работаете в сборке отладки. Мои результаты после ~ 128 щелчков мыши на устройстве с отладочной сборкой:

Увеличение потребления памяти после ~ 128 кликов на устройстве.

Как вы можете видеть, подавляющее большинство потребления памяти связано с инструментами производительности, связанными с отладкой. Вы можете отключить эту функцию, если хотите подтвердить ее, отредактировав свою схему:

изменить вашу схему

И затем отключить запись в обратном направлении:

Отключить запись backtrace.

При отключенном отключении те же ~ 128 кликов практически не увеличиваются:

Нет увеличения потребления памяти после ~ 128 кликов на устройстве.

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

Для справки, это был код, который я запускал:

import UIKit
import FirebaseDatabase

class ViewController: UIViewController {

    @IBOutlet weak var label: UILabel!
    private var count: Int = 0

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    @IBAction func testBtnPressed(sender: AnyObject) {
        let db = FIRDatabase.database().reference()
        db.child("posts").observeSingleEventOfType(.Value) { [weak self] (snap: FIRDataSnapshot!) in
            guard let this = self else { return }
            this.count = this.count + 1
            this.label.text = "\(this.count)"
        }
    }
}

Ответ 2

Я так думаю, это поможет и в xcode. Я сделал это в своем приложении для Android.

DatabaseReference ref = FirebaseDatabase.getInstance().getReference("BLAH_BLAH_STRING");

            // Attach a listener to read the data at our posts reference
            ref.addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    // Do Some Stuff
                    ref.removeEventListener(this);
                    ref = null;

                }

                @Override
                public void onCancelled(DatabaseError databaseError) {
                }
            });

Или в iOS, я думаю, у них есть разные методы, которые будут использоваться.

removeAllObservers и removeObserverWithHandle:

Попробуйте использовать приведенные выше два метода.