Swift Closes[无主单身汉]

Swift Closes[无主单身汉],swift,memory-management,closures,Swift,Memory Management,Closures,Swift中存在递归内存泄漏问题,其中一个单例在另一个单例的闭包内被调用 NetworkManager.sharedInstance.doThingWithCompletion(urlString) { [unowned self] (complete) -> Void in if complete == true { if self.fetchedResultsController.fetchedObjects?.count > 0 {

Swift中存在递归内存泄漏问题,其中一个单例在另一个单例的闭包内被调用

NetworkManager.sharedInstance.doThingWithCompletion(urlString) { [unowned self] (complete) -> Void in

       if complete == true {

           if self.fetchedResultsController.fetchedObjects?.count > 0 {

               CoreDataManager.sharedInstance.save(self.dictionary, completion: { (complete) -> Void in

            })
        }
    }
}
如何将未拥有的单例添加到捕获列表中?我应该这样做吗

编辑

Quantaliinuxite发现核心数据管理器出现问题。。。这种架构绝对没有问题

static let sharedInstance = BFSCoreDataManager()

deinit {

    NSNotificationCenter.defaultCenter().removeObserver(self)
}

// MARK: - Saving

func observeContext(context:NSManagedObjectContext) {

    NSNotificationCenter.defaultCenter().addObserver(
        self,
        selector:"mergeChangesFromNotification:",
        name: NSManagedObjectContextDidSaveNotification,
        object: nil) // ** PROBLEM WAS HERE **
}

func mergeChangesFromNotification(notification:NSNotification) {

    dispatch_async(dispatch_get_main_queue()) {

        self.managedObjectContext.mergeChangesFromContextDidSaveNotification(notification)
    }
}

也许值得看看你是如何定义你的单身汉的。一般来说,我会这样做:

class MySingleton {
    static let sharedInstance = MySingleton() //The singleton
}
NetworkManager.sharedInstance.doThingWithCompletion(urlString) { 
    [unowned self, unowned dataManager = CoreDataManager.sharedInstance] (complete) -> Void in

    if complete {

        if self.fetchedResultsController.fetchedObjects?.count > 0 {

            dataManager.save(self.dictionary, completion: { (complete) -> Void in

            })
        }
    }
}
这会留下一个干净的堆栈跟踪,并且不会引起混淆。供参考:

编辑:

该bug似乎位于
BFSCoreDataManager
类中。 在
observerContext:
中,您忘记了听上下文。该功能应为:

func observeContext(context:NSManagedObjectContext) {

    NSNotificationCenter.defaultCenter().addObserver(
        self,
        selector:"mergeChangesFromNotification:",
        name: NSManagedObjectContextDidSaveNotification,
        object: context) //context instead of nil
}

我不知道这是否能解决内存管理问题,但将单例包含在捕获列表中的方法如下:

class MySingleton {
    static let sharedInstance = MySingleton() //The singleton
}
NetworkManager.sharedInstance.doThingWithCompletion(urlString) { 
    [unowned self, unowned dataManager = CoreDataManager.sharedInstance] (complete) -> Void in

    if complete {

        if self.fetchedResultsController.fetchedObjects?.count > 0 {

            dataManager.save(self.dictionary, completion: { (complete) -> Void in

            })
        }
    }
}

还要注意,当检查
Bool
值时,不需要将其与
true
进行比较
if complete==true{…}
可以缩短为
if complete{…}

我们如何准确地将单例定义为“泄漏”?根据他们的本性,他们永远不会被释放…是的,很好。。为了定义它,调用内部单例方法会使内存呈指数级增长,直到崩溃。即使方法为空,CDM单例也不会在任何时候调用NetworkManager?您可以为调试做一些事情,看看堆栈跟踪,看看整个递归shenanigan是关于什么的。对于子孙后代来说,CDM总是NetworkManager的下风。让我们来看看。如果我学究的话,应该是静态的。对于子孙后代来说,两者都是这样定义的。再次感谢Quantalinuxiteok,这太棒了。。。我会看看如何添加这些内容,看看效果如何。谢谢你的帮助,知道这些很方便