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
})
}
Ответы
Ответ 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:
Попробуйте использовать приведенные выше два метода.