Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Overview

EOSharedEditingContext, which should more appropriately be named EOReadOnlyEditingContext (or EOReadMostlyEditingContext), provides an editing context that can be used across your entire application for keeping globally shared EO's in memory. While it is possible to make changes to objects in a shared editing context, it is notoriously difficult to do so without creating problems such as a deadlocks. The best type of objects to put in a shared editing context are those that change very infrequently like enumerated type objects, for instance.

Performance Implications

There is a performance hit on your Application when EOSharedEditingContexts are enabled. If your application does not use them, you should call:

Code Block
  EOSharedEditingContext.setDefaultSharedEditingContext(null);

in your Application constructor. This will disable shared editing contexts completely, and you will no longer see any performance loss.

Art Isbell

If you haven't done so, consider reading Apple's Documentation.

...

Only those objects that will never be source objects in relationships with unshared destination objects can be shared. Shared objects should be read-mostly as well because updating them requires a special procedure.

Jonathan Rochkind

Wiki Markup
\[I personally have always been scared of using EOSharedEditingContexts, because there seemed such potential for problems. They are complex in how they work, not entirely well documented, and I suspected there would be Apple bugs.

Robert A Decker

However, one user kindly provided his own guidelines he uses with EOSharedEditingContexts, and which he says results in no problems at all. I include his guidelines here.

...

Again, do not fetch using the shared ec. Using this simple rule I haven't had any problems with objects that are changed rarely while the app is running. I've deleted and updated up to thousands of objects in separate threads using these rules without problems.

Robert A Decker

and on how the objects get in the shared ec in the first place, rob writes:

...

Code Block
public static void refreshSharedEntity(String entityName) throws MarvinGeneralException {
   Application.refreshSharedEntityForFetchSpecificationName(entityName,   "FetchAll");    
}
  
public static void refreshSharedEntityForFetchSpecificationName(String entityName, String fetchSpecName) 
        throws MarvinGeneralException {
  EOModelGroup modelGroup = EOModelGroup.defaultGroup();
  EOSharedEditingContext sharedEC =
  EOSharedEditingContext.defaultSharedEditingContext();
  EOFetchSpecification fs = modelGroup.fetchSpecificationNamed(fetchSpecName, entityName);
        
  if (fs == null) {            
    throw new MarvinGeneralException(Application.class.getName() + ".refreshSharedEntityForFetchSpecificationName", 
            entityName + "." + fetchSpecName + " doesn't exist");        
  } else {
    sharedEC.bindObjectsWithFetchSpecification(fs, fetchSpecName);        
  }
}

I use these methods for updating the shared editing context for a specific entity.

...

Code Block
public static NSArray enclosureMasters() {
  NSDictionary objectsByEntityName = (NSDictionary)EOSharedEditingContext.defaultSharedEditingContext()
          .objectsByEntityNameAndFetchSpecificationName();
  NSDictionary objectsForEnclosureMaster = (NSDictionary) objectsByEntityName.objectForKey("EnclosureMaster");
  NSArray enclosureMasters = (NSArray) objectsForEnclosureMaster.objectForKey("FetchAll");
  return enclosureMasters;
}
  
public static NSArray enclosureMasters(String fetchSpecName, NSDictionary bindings) {
  // filter in memory against all enclosure masters 
  // EOQualifier.filteredArrayWithQualifier( NSArray objects, EOQualifier aQualifier)
  
  if (bindings == null) bindings = new NSDictionary();
  EOFetchSpecification fetchSpec = EOFetchSpecification.fetchSpecificationNamed(fetchSpecName, "EnclosureMaster");
  EOQualifier boundQualifier = fetchSpec.qualifier().qualifierWithBindings(bindings, 
          fetchSpec.requiresAllQualifierBindingVariables());
  if (boundQualifier == null) return
  EnclosureMaster.enclosureMasters(); // return all - 
             // otherwise the next call will give us an empty array
  NSArray results = EOQualifier.filteredArrayWithQualifier(EnclosureMaster.enclosureMasters(), boundQualifier);
  // we should now use the fetchSpec's sort orderings to sort the results
  NSArray sortedResults = results;
  NSArray sortOrderings = fetchSpec.sortOrderings();
  if (sortOrderings != null)
    sortedResults = EOSortOrdering.sortedArrayUsingKeyOrderArray(results, sortOrderings);
  return sortedResults;
}

...

When you addd a new object you have to reload by calling, for example,

Code Block
  Application.refreshSharedEntity("EnclosureMaster";);

When you edit or delete a shared entity the SharedEditing context will take care of updating the objects it's holding.Category:WebObjects