-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathSSYMOCManager.h
228 lines (189 loc) · 11 KB
/
SSYMOCManager.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
#import <Cocoa/Cocoa.h>
@class BSManagedDocument;
/*!
@brief Manages a multitude of managed object contexts for an application.
@details Provides managed object contexts of the volatile in-memory and/or
nonvolatile sqlite type, identifying them later with an <i>identifier</i>
and, later, given a managed object context created by this class, identifying
its <i>owner</i>, an id which was given when the managed object context was
created. Also searches through the application's NSPersistentDocuments to
find the NSPersistentDocument <i>owner</i> if a managed object context for
which the owner is desired turns out to not be one of this class's creations.
This class itself is instantiated as an app-wide
singleton and no public instance methods are available.
UPDATE 2018-12-28. I do not recommend using this class, which I wrote I
think in 2009, any more, because it is easy to cause retain cycles which are
tricky to unravel.
When using this class, [NSApp delegate] must conform to protocol
SSYAppSupporter.
*/
@interface SSYMOCManager : NSObject {
NSMutableDictionary* inMemoryMOCDics ;
NSMutableDictionary* sqliteMOCDics ;
NSMutableDictionary* docMOCDics ;
}
/*!
@brief Returns path to the directory in which the receiver's SQLite
MOCS reside on disk.
*/
+ (NSString*)directoryOfSqliteMOCs ;
/*!
@brief Returns whether or not a persistent (sqlite) store exists
for a given identifier.
@details Because +managedObjectContextType:::::: creates
a new store if the one you ask for does not exist, you need to use this
method to determine a store's existence.
@param identifier The identifier of the desired store
@result YES if the store exists on disk, otherwise NO.
*/
+ (BOOL)sqliteStoreExistsForIdentifier:(NSString*)identifier ;
/*!
@brief Returns a new or pre-existing managed object context which will
access a new or pre-existing store.
@details Provides managed objects in different contexts/stores, segregated from one another.
If managed objects are created to be in one of several groups, and not often migrate
migrate to other groups, it is better to store these in segragated stores like this
rather than to throw them all in the same store and filter them during fetches with an
identifying attribute. The reason is that the identifying attribute will cause an extra
subpredicate that will increase fetch times, or require post-fetch filtering which will add
about the same execution time.
This method searches the app-wide singleton for a managed object context of the required
type and identifier and returns it if found. Otherwise, a new store and managed object
context are created, retaining with it the provided owner. If a new managed object
context must be created and the 'owner' parameter is nil, the owner will be set to NSApp.
If a managed object context is created with nil 'owner', this is assumed to be a "temporary
storage" or "cheap" moc for which undo support is not needed. Its undoManager is set
to nil. Such a moc will execute more cheaply.
This method retains a reference to the managed object context (in any of the three MOCDics).
To avoid leaks or retain cycles, send a
+destroyManagedObjectContext: message whenever a managed object context returned from this
method is no longer needed.
@param type NSSQLiteStoreType or NSInMemoryStoreType.
@param owner If a new managed object context must be created, an arbitrary object which
will be retained as its <i>owner</i>. Otherwise, this parameter is ignored.
@param identifier A unique identifier for the context/store, or nil to return
a "common" managed object context/store of the given type for the application.
If storeType is NSSQLiteStoreType, identifier must contain only characters that are valid
in a filename. That means, I believe, in macOS, no slashes (/) or colons (:).
This is because the identifier will be incorporated the name of an sqlite database
file that will be created to support the new managed object context if necessary.
@param momdName The baseName of the baseName.momd directory in
the application's Resources which contains the various versions of
managed object models (.mom) files required to migrate an existing
sqlite store. This parameter is needed to perform multi-hop migration
of existing sqlite stores by CoreDataProgressiveMigration classes.
If you do not wish to support multi-hop migration, you may pass nil
and only Core Data's built-in single-hop automatic migration will
be used. For store types other than sqlite, this parameter is ignored.
@param nukeAndPaveIfCorrupt. If YES, and if the requested managed object
context cannot be created becaus the underlying store file on the disk is
corrupt, will silently delete the file and start a new empty one as if nothing
bad happened. Ignored if the storeType is not NSSQLiteStoreType.
@param error_p If managed object context could not be created, points to an NSError
on output. This should not occur for NSInMemoryStoreType, only NSSQLiteStoreType.
@result The new or pre-existing managed object context, or nil if one could not be created.
*/
+ (NSManagedObjectContext*)managedObjectContextType:(NSString*)storeType
owner:(id)owner
identifier:(NSString*)identifier
momdName:(NSString*)momdName
nukeAndPaveIfCorrupt:(BOOL)nukeAndPaveIfCorrupt
error_p:(NSError**)error_p ;
/*!
@brief Adds a managed object context to the document managed object contexts
managed by the shared MOC manager.
@details Do this so that the +ownerOfManagedObjectContext: method will work
for the managed objects.
This method retains the -document parameter until it receives a corresponding
+destroyManagedObjectContext message, so be careful or you will create retain
cycles. This method will, however, *replace* its record for a particular
document if you later send this message again for the same document with a new
or same managedObjectContext.
@param document The document which will own the managed object context
@param managedObjectContext The managed object context to be registered.
*/
+ (void)registerOwnerDocument:(BSManagedDocument*)document
ofManagedObjectContext:(NSManagedObjectContext*)managedObjectContext ;
/*!
@brief Returns the owner of a given managed object context, or if it turns out to have not
been created by this class, the NSPersistentDocument to which it belongs.
@details This method searches its instance data looking for the owner that was provided when
a managed object context was returned by the receiver's -managedObjectContextType::::::.
If none is found, then it seaches the application's NSDocumentController's
-documents, looking for an NSPersistentDocument subclass which returns a -managedObjectContext
that matches the given managedObjectCcontext.
@param managedObjectContext The managed object context for which the owner is desired.
@result The owner of the given managed object context, or nil if the given managed object
context is not found in either in the receiver's instance data or as the -managedObjectContext of
any document.</p>
<p>Usage tip: To allow <i>managed objects</i> to access their "owners", subclass NSManagedObject
and provide a method which returns
[SSYMOCManager ownerOfManagedObjectContext:[self managedObjectContext]]. Then use this
method to get the owner.</p>
*/
+ (id)ownerOfManagedObjectContext:(NSManagedObjectContext*)managedObjectContext ;
/*!
@brief Removes a managed object context returned by -managedObjectContextType::::::
from the receiver's instance's data.
@details This method releases the receiver's retain count on the managed object
context, if the receiver has a record of it. Send a this message whenever a
managed object context returned by -managedObjectContextType:::::: is no longer
needed, in order to avoid memory leaks in your program. To avoid retain cycles,
don't do it in -dealloc. Put it in a method which runs prior to -dealloc.
It is OK to send this message more than once; further invocations will no-op.
However, note that SSYMOCManager does not have a retain count mechanism. That
is why this method is named "destroy…" instead of "release…". If more than one
of your objects could be using the subject managed object context, it is your
responsibility to not send this message until all such objects no longer need
it.
@param managedObjectContext The managed object context to be removed.
@return YES if an entry with the given managed object context was found and removed,
otherwise NO.
*/
+ (BOOL)destroyManagedObjectContext:(NSManagedObjectContext*)managedObjectContext ;
/*@brief Removes any managed object context with a give identifier,
which would be returned by -managedObjectContextType:::::, from the
receiver's instance's data.
@details Ditto the details from +destroyManagedObjectContext:.
*/
+ (void)destroyManagedObjectContextWithIdentifier:(NSString*)identifier ;
/*!
@brief Deletes the local store file on disk for an sqlite store with a given
identifier
@details This is useful in "Trash the Cache" or similar operations.
*/
+ (void)removeSqliteStoreForIdentifier:(NSString*)identifier ;
/*!
@brief Returns the URL of an sqlite store with a given
identifier, without regard to whethe or not it exists in
the filesystem.
@details An internal method, exposed here because it is sometimes useful for
troubleshooting, or if you want to use concurrency by creating another Core
Data stack based on the same store.
*/
+ (NSURL*)sqliteStoreURLWithIdentifier:(NSString*)identifier ;
+ (BOOL)isInMemoryMOC:(NSManagedObjectContext*)moc ;
+ (BOOL)isSqliteMOC:(NSManagedObjectContext*)moc ;
+ (BOOL)isDocMOC:(NSManagedObjectContext*)moc ;
/*!
@brief Returns a managed object context, backed by a in-memory store, using
your application's merged managed object models, and nil undo manager
@details You can use this to create isolated, temporary managed object(s)
which you may need to use their behaviors. The alternative, creating such
objects in one of your application's "real" managed object contexts, and then
deleting these objects when done, may have undesired side effects such as
triggering notifications.
To create such a temporary object, alloc a NSManagedObject and then
-initWithEntity:insertIntoManagedObjectContext:.
If you call this method on the main thread, the result will have
NSMainQueueConcurrencyType; otherwise, NSPrivateQueueConcurrencyType. This
is so that you can "just use it", wherever you are.
*/
+ (NSManagedObjectContext*)scratchManagedObjectContext;
+ (NSManagedObjectContext*)pasteboardManagedObjectContext;
+ (NSArray <NSManagedObject*>*)deepCopiesForPasteboardObjects:(NSArray <NSManagedObject*> *)objects
doNotEnterRelationshipNames:(NSSet <NSString*> *)relationshipNames;
#if DEBUG
+ (void)logDebugCurrentSqliteMocs ;
#endif
@end