Memory leak on NSPredicate that used in fetch request to fetch NSManagedObject

江枫思渺然 提交于 2019-12-12 17:22:26

问题


According to the instrument I have memory leak on the NSPredicate. How can I avoid this memory leak? what went wrong?

The code as the following: Note :

Default Manager is Singleton

self.editingContext is a child context that has a parent context (main context)

The output of this function (JobType) is NSManagedObject that use in the parent NSManagedObject (e.g job.type = jobType)

func defaultJobType() -> JobType?
{
  let fetchRequest = NSFetchRequest(entityName: JobType.entityName());

  let predicate = NSPredicate(format: "jobTypeID = %@ && (archived = nil || archived = 0)", DefaultManager.instance.defaultValues[DJobType]!.uppercaseString);

  fetchRequest.predicate = predicate;

  do{
    return try self.editingContext?.executeFetchRequest(fetchRequest).first as? JobType;
  }
  catch let error as NSError
  {
    Logger.logApplicationError("Error in getting default job Type", detailMessage: error.localizedDescription);
  }
  catch
  {
    Logger.logApplicationError("Error in getting default job Type", detailMessage: "No detail error found");
  }

  return nil;
}

The caller of the function defaultJobType()

func createDefaultJob() -> Job
{
    let job = Job.MR_createInContext(self.editingContext!) as! Job;
    job.assignedUserID = LoginManager.sharedInstance().currentUserID;
    job.createdBy = LoginManager.sharedInstance().currentUserID;
    job.createdOn = NSDate();
    job.lastModifiedByUser = LoginManager.sharedInstance().currentUserID;

    if let defaultCallout = self.servicesDefault.defaultCalloutFee() {
        if let jobCalloutFee = defaultCallout.createJobCalloutFee()
        {
            job.addJobCalloutFeesObject(jobCalloutFee);
        }
    }

    job.type = self.servicesDefault.defaultJobType();

    return job;
}

And createDefaultJob() is used in Objective C ViewController.

Please help


回答1:


I just encountered the same issue as well. It was not there before iOS 9. There is also a radar here

I managed to solve it by re-configuring my core data stack. Basically, I was running into the problem when I was using a parent managed context (main) and a nested child managed context:

I changed my parent and child context to two (not nested) separate contexts sharing the same persistence store coordinator. I manually merged the changes as follows:

let moc = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
moc.persistentStoreCoordinator = coordinator

let privateMoc = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
privateMoc.persistentStoreCoordinator = coordinator

NSNotificationCenter.defaultCenter().addObserverForName(NSManagedObjectContextDidSaveNotification, object: moc, queue: nil) { notification in
privateMoc.performBlock {
                privateMoc.mergeChangesFromContextDidSaveNotification(notification)
            }
    }

I run the leaks instrument and the leaks are gone. Hope this helps.



来源:https://stackoverflow.com/questions/33272197/memory-leak-on-nspredicate-that-used-in-fetch-request-to-fetch-nsmanagedobject

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!