使用Firebase发生内存泄漏

时间:2019-03-11 00:38:58

标签: ios swift firebase memory-leaks

我在Firebase中执行API调用,以检索用户个人资料信息并将其存储在ViewController成员变量中。 该API在类MyApi中声明为静态函数:

// Get User Profile
    static func getUserProfile(byID userId:String,response:@escaping (_ result:[User]?,_ error:Error?)->()) {

        // check ID is valid
        guard userId.length > 0 else {
            print("Error retrieving Creator data: invalid user id provided")
            response(nil,ApiErrors.invalidParameters)
            return
        }

        // retrieve profile
        let profilesNode = Database.database().reference().child(MyAPI.profilesNodeKey)
        profilesNode.child(userId).observe(.value, with: { (snapshot) in
            // check if a valid data structure is returned
            guard var dictionary = snapshot.value as? [String:AnyObject] else {
                print("Get User Profile API: cannot find request")
                response([],nil)
                return
            }

            // data mapping
            dictionary["key"] = userId as AnyObject
            guard let user = User(data:dictionary) else {
                print("Get User Profile API: error mapping User profile data")
                response(nil,ApiErrors.mappingError)
                return
            }
            response([user], nil)
        }) { (error) in
            response(nil,ApiErrors.FirebaseError(description: error.localizedDescription))
        }
    }

我这样称呼它:

MyAPI.getUserProfile(byID: creatorId) { (profiles, error) in
            guard let profiles = profiles, profiles.count > 0 else {
                Utility.showErrorBanner(message: "Error retrieving Creator profile")
                print("Error retrieving creator profile ID:[\(creatorId)] \(String(describing: error?.localizedDescription))")
                return
            }
            self.currentProfile = profiles.first!
        }

ViewController是在Modal模式下调用的,因此每次我退出屏幕时都应该将其释放。

问题:进入屏幕时会分配很大的内存,但是当我离开屏幕时不会释放它。我对此很有把握,因为(显然)如果我删除了self.currentProfile = profiles.first!行,该问题就不会出现

如何避免这种情况发生?

注意currentProfile的类型为User,以前是struct。我将其设置为一个类,以便可以使用弱引用来存储信息:

weak var currentCreator: User? {
        didSet {
            updateView()
        }
    }

但是问题仍然存在。

1 个答案:

答案 0 :(得分:3)

您要添加一个观察者:

profilesNode.child(userId).observe(...)

但是您永远不会删除它。只要仍添加该观察值,它将从整个结果集中保留到内存中,并不断检索新的更新。不删除观察者是非常糟糕的做法。

如果您想read data just a single time,则有一个使用observeSingleEvent的API。