【问题标题】:Firebase observeSingleEvent stays in memoryFirebase observeSingleEvent 留在内存中
【发布时间】:2016-12-30 06:16:55
【问题描述】:

我的应用相当多地使用了 firebase 的 observeSingleEventOfType,我开始意识到我的应用的内存会随着时间的推移而增加。除了调用以下函数的测试按钮外,我已经注释掉了所有代码。

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

程序启动时,我以大约每秒 2.3 次的速度快速按下测试按钮,观察内存图如下所示。内存在请求后上升并且不会下降。从长远来看,这个问题对我的应用程序的影响相当大,因为我的应用程序的内存将从 70mb 增长到 150+mb。这有什么原因吗?

注意,短暂的五秒休息让我停下来确保打印出所有“快照”。

注意 2... 当我停止按下按钮时,内存保持在“短暂休息部分”中所示的相同水平。以防你认为它会无限期地自行生长

-------更新---------

为了进一步确认问题,我创建了一个全新的项目,其中除了 firebase 导入之外什么都没有,故事板上的一个按钮带有以下代码并在我的 6s 上模拟(在模拟器上模拟似乎没有这个问题)。下图证明了 Firebase 发生了一些可疑的事情,因为我的内存在一分钟左右的时间内从 11.1mb 变为 17.3mb,有 303 个请求。

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
    })
}

【问题讨论】:

  • 当您使用.observeEventOfType时,这种情况是否仍然存在
  • 是的。但是,结果略有不同。 ObserveEventOfType 的上升速度比 ObserveSingleEventOfType 慢一点。
  • 等等,这很有趣,我自己测试一下......
  • 确实...在我的实际代码中似乎是最糟糕的,其中有多个变量和函数可以从我的数据库中获取点点滴滴(如第一张图片所示)
  • 嘿,我什至做了一个全新的应用程序来验证你的理论.....不检查!,你的快照太大了吗?完成后确保删除观察者..

标签: ios swift xcode firebase firebase-realtime-database


【解决方案1】:

我认为这种方式对 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 中,我猜他们有不同的方法可以使用。

removeAllObserversremoveObserverWithHandle:

请尝试上述两种方法。

【讨论】:

  • 我的项目主要使用observeSingleEventOfType。使用该功能,我认为不需要删除观察者,因为没有什么可以删除
  • 这也是我的理解:每次单击按钮时都会创建一个新的事件侦听器。还是用新的自动休息?
【解决方案2】:

这可能只是因为您在调试版本上运行。我的结果,在带有调试版本的设备上点击了大约 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)"
        }
    }
}

【讨论】:

  • 谢谢你!这似乎是我尝试后的问题。虽然如果我在不禁用“启用回溯录制”的情况下将其置于释放模式,内存仍然会增长。这是否意味着发布模式仍然使用回溯记录?
  • 好吧,是的,如果你在启用它的情况下启动它。不过,您的用户不会以这种方式启动它。尝试取消选中“调试可执行文件”选项。您仍然可以在调试器启动后附加调试器(调试器 > 附加到进程)以查看内存使用情况......这对我来说也很有用。
  • 基本上,如果您的应用程序在附加调试器并启用该选项的情况下启动,您将看到此问题。禁用该功能或​​在启动时未附加调试器,问题就消失了。真正的用户是不会体验到的,纯属调试的神器。我不知道这是从 Apple 的角度来看的预期行为,还是实际的错误,无论哪种方式......它不应该影响您的实际用户。
  • 不知道为什么,但是每当我使用仪器时,即使选中了“启用回溯记录”,我也没有这个问题。所以我没有得到你图片中显示的结果(因此我无法使用仪器确定问题所在)。我只能在使用内置的 Xcode 内存图时观察到这种效果。您对此有何看法?
  • 我认为不同之处在于我使用“Profile in Instruments”按钮将应用程序传输到 Instruments。如果我直接从 Instruments 启动它,行为就像你描述的那样。一种特殊的、微妙的差异,您不会期望产生不同的结果,但似乎确实如此。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-12
  • 2017-12-17
  • 2020-06-01
  • 2017-07-19
  • 2019-02-27
  • 1970-01-01
相关资源
最近更新 更多