Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow unshared instances of the manager #101

Merged
merged 9 commits into from
Oct 17, 2016

Conversation

vokal-isaac
Copy link
Contributor

In order to allow multiple instances of VOKCoreDataManager to coexist:

  • any instance methods on VOKCoreDataManager should use self instead of the shared instance
  • any class methods that require an instance of VOKCoreDataManager should be converted to instance methods (_breaking change_)
  • VOKCoreDataManager should not use any methods from NSManagedObject+VOKManagedObjectAdditions that require a manager instance

The methods in NSManagedObject+VOKManagedObjectAdditions that require a manager instance are now all convenience wrappers that call instance methods on the shared manager. This means that having multiple manager instances means using the manager methods directly rather than the convenience category methods on the managed objects.

@vokal/ios-developers @chillpop Code review please?

@chillpop
Copy link
Contributor

Is the idea to allow multiple instances in addition to the sharedInstance, or deprecate the sharedInstance entirely?

@vokal-isaac
Copy link
Contributor Author

In addition to sharedInstance. I think the vast majority of the time, sharedInstance is the way to go. I just happen to be looking at a particular use case on macOS where the data for a document is represented with an in-memory Core Data store and multiple documents can be open at once. I think having a manager per document is cleaner than designing the Core Data models to allow multiple documents' models to coexist in a single store.

}

return vok_entityName;
return [[VOKCoreDataManager sharedInstance] entityNameForClass:self];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that the idea is to use instances at the same time as the sharedInstance, I think this method (vok_entityName) should be deprecated in favor of using the instance method on VOKCoreDataManager. If your managed object is not in the shared instance's object model, you won't get the right value here. Eg: it's in a different MOM on a separate Vokoder instance.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My inclination was to leave it in place in the same spirit as the rest of the methods in the category—they're fine if you're only using sharedInstance and they're totally wrong/broken if you're not.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That expectation should be prominently documented in the header for this category.

}
}];
VOKCoreDataManager *coreDataManager = VOKCoreDataManager.sharedInstance;
[coreDataManager importArrayInBackground:inputArray
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the plan for using this and other convenience methods with a non-shared VOKCoreDataManager? You can't?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. Basically, the convenience methods in NSManagedObject+VOKManagedObjectAdditions are (now that vok_entityName has been rewritten) just wrappers around methods on the manager, so if one needs a manager-specific call, passing the manager in as an argument to a method on the managed object seemed uglier than calling the method on the manager with the managed object as an argument.

There probably should be an explicit note to the effect of "things in NSManagedObject+VOKManagedObjectAdditions use VOKCoreDataManager.sharedInstance."

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sound good.

cacheName:(NSString *)cacheName
tableView:(UITableView *)tableView
sectionNameKeyPath:(NSString *)sectionNameKeyPath
sortDescriptors:(NSArray *)sortDescriptors
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe all the parameters from here and above should be marked nullable.
Also: this one should be VOKArrayOfSortDescriptors to get a typed array

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops. I really wish Xcode's autocomplete on the .m side would carry over the nullability annotations, etc., from the .h side. (This was copied back from the .m, hence missing all that stuff.)

managedObjectClass:(Class)managedObjectClass
batchSize:(NSInteger)batchSize
fetchLimit:(NSInteger)fetchLimit
delegate:(id <VOKFetchedResultsDataSourceDelegate>)delegate;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nullable here too

@@ -97,7 +99,7 @@ - (void)setResource:(nullable NSString *)resource
}

// Touch the managed object context to ensure it's been created
[[VOKCoreDataManager sharedInstance] managedObjectContext];
[self managedObjectContext];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

self.managedObjectContext?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dislike the dot notation when we're using it for a side-effect, which feels off anyway... but maybe (void)self.managedObjectContext;, to acknowledge that we're not using the retrieved value?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Enh, keep it as is. I wasn't paying attention to the context of the call.

Copy link
Contributor

@brockboland brockboland left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a good way to unit-test multiple VOKCoreDataManagers?

This change also merits some additional documentation. Could you add something brief to the README, just noting that multiple instances are supported?

}

return vok_entityName;
return [[VOKCoreDataManager sharedInstance] entityNameForClass:self];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That expectation should be prominently documented in the header for this category.

fetchLimit:(NSInteger)fetchLimit
delegate:(id <VOKFetchedResultsDataSourceDelegate>)delegate
{
return [self initWithCoreDataManager:VOKCoreDataManager.sharedInstance
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would pass nil here to let the designated initializer handle it

@@ -302,7 +309,7 @@ typedef void(^VOKObjectIDsReturnBlock)(VOKArrayOfManagedObjectIDs *managedObject
@param objectClass Specifies the class to instantiate or fetch when importing data.
@param completion Fired on the main queue once the changes have been merged. It brings an NSArray of permanent NSManagedObjectIDs matching the objects deserialized from the import array.
*/
+ (void)importArrayInBackground:(VOKArrayOfObjectDictionaries *)inputArray
- (void)importArrayInBackground:(VOKArrayOfObjectDictionaries *)inputArray
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't find it now, but I thought there was a compiler macro to indicate that some method has been replaced with another one, so that Xcode can suggest the appropriate correction. I can't find it now, but if that rings any bells, it might be helpful to include it here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

…here and for writeToTemporaryContext above, that is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I left the old methods in place, they could be tagged with the deprecation macro with a message pointing to the new methods.

I'd say maybe we add the instance methods to 3.x and mark the class methods as deprecated there, with the note that they'll be removed in 4.x?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We discussed this in person, but: nah, I'd rather just move forward with the changes in 4.x and leave 3.x where it is.

@@ -8,6 +8,8 @@
#import "VOKCoreDataManager.h"
#import "VOKCoreDataManagerInternalMacros.h"

#import <objc/runtime.h>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this import can be removed from NSManagedObject+VOKManagedObjectAdditions.m. I can't comment on the line over there because it's not part of the diff.

@@ -631,36 +682,38 @@ - (void)saveAndMergeWithMainContextAndWait:(NSManagedObjectContext *)context;

#pragma mark - Background Importing

+ (void)writeToTemporaryContext:(VOKWriteBlock)writeBlock
- (void)writeToTemporaryContext:(VOKWriteBlock)writeBlock
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same thing in a couple places here, regarding that compiler macro for replaced methods (if we find it)

@brockboland
Copy link
Contributor

@chillpop @bryanluby any other feedback on this one?

@chillpop
Copy link
Contributor

still LGTM

@bryanluby
Copy link
Contributor

LGTM

@brockboland brockboland merged commit 0b905dc into vokal:master Oct 17, 2016
@vokal-isaac vokal-isaac deleted the feature/allowUnsharedInstances branch November 4, 2016 19:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants