3lvis / datastack Goto Github PK
View Code? Open in Web Editor NEW100% Swift Simple Boilerplate Free Core Data Stack. NSPersistentContainer
License: Other
100% Swift Simple Boilerplate Free Core Data Stack. NSPersistentContainer
License: Other
HI! I have following code, the problem is that i gets executed but it never saves the modified inspection.
I am honestly not sure if it is my mistake or not. Would you mind to take a look?
func uploadAndUpdateInspection(inspection : Inspection) {
let equipment = inspection.equipment! as Equipment
let equipmentType = equipment.equipmentType! as EquipmentType
let company = equipmentType.company! as Company
let parameters = [
"companyId": company.remoteID!,
"equipmentId": equipment.remoteID!
]
Alamofire.request(.POST, self.kBaseURL + "/inspection/new", parameters: parameters , encoding: .JSON).responseJSON
{ response in switch response.result {
case .Success(let JSON):
if let value = JSON as? [String: AnyObject] {
inspection.remoteID = value["inspectionId"] as! Int
inspection.synced = true
debugPrint(inspection)
do {
try self.dataStack.mainContext.save()
LOG()
}catch{
assert(false)
}
}
break
case .Failure(let error):
break
}
}
}
func uploadInspection(){
let fetchRequest = NSFetchRequest(entityName: "Inspection")
let fetchedEntities = try! self.dataStack.mainContext.executeFetchRequest(fetchRequest) as! [Inspection]
debugPrint(fetchedEntities)
for inspection in fetchedEntities {
self.uploadAndUpdateInspection(inspection)
}
}
Thank you.
http://developer.android.com/reference/android/os/StrictMode.html
Don't allow saves in the main thread
Let's assume core data entity structure like this:
Cart:
-> CartEntry - To-Many, Optional
CartEntry:
-> product -> To-One, Optional
There is CartEntry with product in my Cart - coreData seems to be ok.
I'm fetching Cart and as a result I've got:
Cart:
-> entries: [
{
product: nil
}
]
However when I changed
Cart:
-> CartEntry - To-Many
Everything seems to be fine - fetch result got also products.
I need a way to initialize DATAStack with a given ManagedObjectModel as the model is not in bundle I can access.
Looking for help on how I would use this with FetchRequestTemplate?
Thanks
If a .sqlite
file has been added to the project that has the same name as the Core Data model, then the contents of this sqlite file should be used to pre-fill Core Data.
NSString *alertTitle = NSLocalizedString(@"Error encountered while reading the database. Please allow all the data to download again.", @"[Error] Message to show when the database is corrupted");
[[[UIAlertView alloc] initWithTitle:alertTitle
message:nil
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil] show];
Hi,
I am using a DataStack created as follows:
self.dataStack = DATAStack(modelName: "money", isExcludedFromBackup: false)
This should then be included in iTunes/iCloud backups. I wanted to check this, so I downloaded iPhone Backup Extractor from here (https://www.iphonebackupextractor.com/blog/ios-data-recovery-apps-data-iphone-backups/), made a new iTunes backup and then checked the backup using this app. Although I can see the SQLite file (under com.myapp.title/Library/Application Support/myapp.sqlite
), if I extract it and then open the SQLite file using a SQLite viewer, it doesn't contain any actual data from my app. It does contain the full database structure though.
Do you have any ideas what might be causing the data to be missing from the backup?
Thanks
Hi I am using Sync and your framework to save my JSON data
how to fetch my data fro the coredata I see no instructions of fetching data using DATAStack
can you please help me out
thank you
https://github.com/NSElvis/DATAStack/blob/master/Tests/Tests/Tests.m#L98
In the example of running test i need to make a __bloc variable to work with it.
That looks not perfect :(, good but not perfect.
I would prefer to have a method without completion block
I'm not sure what's going on, but I've been blocked by this issue for >= 48 hours. It appears as if none of the insertions on any context are making it to the persistent store coordinator. I've tried everything from changing the mergePolicy
, to manually observing contexts. For whatever reason, changes made in a background context, even after invoking persistWithCompletion
, never update the main context, even after explicit fetches until the application is killed and restarted.
I've tweaked the DemoSwift.ViewController
to demonstrate the issue:
import UIKit
import CoreData
import DATASource
class ViewController: UITableViewController {
var dataStack: DATAStack
var _backgroundContext: NSManagedObjectContext
lazy var dataSource: DATASource = {
let request: NSFetchRequest = NSFetchRequest(entityName: "User")
request.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)]
let dataSource = DATASource(tableView: self.tableView, cellIdentifier: "Cell", fetchRequest: request, mainContext: self.dataStack.mainContext, configuration: { cell, item, indexPath in
if let name = item.valueForKey("name") as? String, createdDate = item.valueForKey("createdDate") as? NSDate, score = item.valueForKey("score") as? Int {
cell.textLabel?.text = name + " - " + String(score)
}
})
return dataSource
}()
init(dataStack: DATAStack) {
self.dataStack = dataStack
self.dataStack.mainContext.stalenessInterval = 0.0
self._backgroundContext = dataStack.newBackgroundContext("_Background Context")
self._backgroundContext.stalenessInterval = 0.0
super.init(style: .Plain)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "Cell")
self.tableView.dataSource = self.dataSource
let backgroundButton = UIBarButtonItem(title: "Background", style: .Done, target: self, action: #selector(ViewController.createBackground))
let customBackgroundButton = UIBarButtonItem(title: "Custom", style: .Done, target: self, action: #selector(ViewController.createCustomBackground))
self.navigationItem.rightBarButtonItems = [customBackgroundButton, backgroundButton]
let mainButton = UIBarButtonItem(title: "Main", style: .Done, target: self, action: #selector(ViewController.createMain))
let dropAllButton = UIBarButtonItem(title: "Edit Main Object", style: .Done, target: self, action: #selector(ViewController.editMainObject))
self.navigationItem.leftBarButtonItems = [dropAllButton, mainButton]
}
func createBackground() {
self.dataStack.performInNewBackgroundContext { backgroundContext in
let entity = NSEntityDescription.entityForName("User", inManagedObjectContext: backgroundContext)!
let object = NSManagedObject(entity: entity, insertIntoManagedObjectContext: backgroundContext)
object.setValue("Background", forKey: "name")
object.setValue(NSDate(), forKey: "createdDate")
try! backgroundContext.save()
}
}
func createCustomBackground() {
let backgroundContext = dataStack.newBackgroundContext("Sync Context")
backgroundContext.performBlock {
let entity = NSEntityDescription.entityForName("User", inManagedObjectContext: backgroundContext)!
let object = NSManagedObject(entity: entity, insertIntoManagedObjectContext: backgroundContext)
object.setValue(backgroundContext.name, forKey: "name")
object.setValue(NSDate(), forKey: "createdDate")
try! backgroundContext.save()
}
}
func createMain() {
let entity = NSEntityDescription.entityForName("User", inManagedObjectContext: self.dataStack.mainContext)!
let object = NSManagedObject(entity: entity, insertIntoManagedObjectContext: self.dataStack.mainContext)
object.setValue("Main", forKey: "name")
object.setValue(1, forKey: "score")
object.setValue(NSDate(), forKey: "createdDate")
//try! self.dataStack.mainContext.save()
self.dataStack.persistWithCompletion()
}
func editMainObject() {
self.dataStack.performInNewBackgroundContext { _backgroundContext in
_backgroundContext.stalenessInterval = 0.0
//_backgroundContext.performBlock {
let fetchRequest = NSFetchRequest(entityName: "User")
fetchRequest.predicate = NSPredicate(format: "%K contains[c] %@", "name", "Main")
let backgroundUsers = try! _backgroundContext.executeFetchRequest(fetchRequest) as! [NSManagedObject]
var i: Int32 = 0
for user in backgroundUsers {
i += 1
let number = NSNumber(int: (123 * i))
user.setValue(number, forKey: "score")
}
try! _backgroundContext.save()
}
//}
}
}
In this example, pressing the "Main" button will create a new User
with a score
of 0. That User
will not be modified by the editMainObject
function when the "Edit Main Object" button is pressed.
If the app is killed and restarted, the "Edit Main Object" button will cause the objects to be modified and updated.
I'm really not sure how to proceed, or if I'm doing something wrong.
Hey,
we got an error when calling drop and then trying to use the stack again. This is due to the fact that the wal and shm file are not deleted (http://stackoverflow.com/questions/18277092/persistentstorecoordinator-sqlite-error-code522-not-an-error). We have implemented a workaround in a subclass for now which fixes the issue.
br
denis
- (void)drop {
NSPersistentStore *store = [self.mainContext.persistentStoreCoordinator.persistentStores lastObject];
NSString *sqliteFile = store.URL.path;
sqliteFile = [sqliteFile stringByDeletingPathExtension];
NSString *shm = [NSString stringWithFormat:@"%@.sqlite-shm", sqliteFile];
NSString *wal = [NSString stringWithFormat:@"%@.sqlite-wal", sqliteFile];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error = nil;
if ([fileManager fileExistsAtPath:shm]) {
[fileManager removeItemAtURL:[NSURL fileURLWithPath:shm] error:&error];
}
if ([fileManager fileExistsAtPath:wal]) {
[fileManager removeItemAtURL:[NSURL fileURLWithPath:wal] error:&error];
}
if (error) {
NSLog(@"ERROR Could not delete persitent store sql or wal file: %@", error.localizedDescription);
}
[super drop];
}
Hi I am new to swift i have stored my json into coredata using sync . But i don't know how can I retrieve datas using DATAStack . Kindly help
Hello,
Any ideas this code fails(EXC_BAD_ACCESS on save()), but with performBlock working OK?
let backgroundContext = App.sharedInstance.dataStack.newBackgroundContext()
let request: NSFetchRequest = NSFetchRequest(entityName: "UserSettings")
let fetched = try! backgroundContext.executeFetchRequest(request) as? [UserSettings]
let record = fetched!.first!
record.setValue(NSDate(), forKey: "updatedAt")
backgroundContext.performBlockAndWait({
try! backgroundContext.save()
})
Carthage Support would be sweet
Hi,
I try to install the library via Cocoapods (in a freshly created Objective-C demo project) and I got the error below:
[!] Unable to determine Swift version for the following pods:
DATAStack
does not specify a Swift version and none of the targets (DNP
) integrating it have theSWIFT_VERSION
attribute set. Please contact the author or set theSWIFT_VERSION
attribute in at least one of the targets that integrate this pod.
Unfortunately couldn't install the library.
my Podfile line is below:
pod 'DATAStack', '~> 6'
Best
It appears that this repo has moved away from using CocoaPods.
If so, the 'Running the demos' install dependencies needs to be updated.
I was not able to run the Carthage build, not sure if it was an issue with Carthage on my machine or not
Thanks - great repo. I'm using both DATAStack and Sync on a project and has great simplified my CoreData life 👍 :)
Jeff
It'd be great to be able to drop a certain collection/entity rather than dropping the full database.
The first part of the drop()
method has this:
let store = self.persistentStoreCoordinator.persistentStores.last
It should probably go through all the persistentStores instead of just removing the last one.
Could anyone tell me how to setup DATAStack on a OS X project?
How to set the AppDelegate File?
I´m trying for days now.
There is no tutorial to be found.
Thank you so much!
First of all sorry for my bad Engish.
I have a project with DATAStack. A lot of users have a problem, when they set a new iPhone from iCloud backup. The data strored in CoreData doesn't exists on the new phone. Should I have to set something to "tell" Apple, that they should backup the sql file? Did you hear about similar issues?
Thanks for your help!
Please kind guide us if there's a table indicated which version of DATAStack should be used for iOS 8.x
We're using following libraries in iOS 9.x which is awesome
It gets messy when comes to iOS 8.x
We check the .sqlite and data were all intact, but the value are all NULL with executeFetchRequest
My data model is being created, but when I try to write to it I get a nilError, this happens with a background context and with a main thread context, is there anything specific I should be looking into? I just copied the example code
Delete requests produce nilError, write requests fail silently
I’m using NSFetchedResultsController and DATAStack. My NSFetchedResultsController doesn’t update my table if I make any changes in another contexts.
I use dataStack.mainContext in my NSFetchedResultsController. If I do any updates from mainContext everything is okay. But if I write such code for example:
dataStack.performInNewBackgroundContext({ (backgroundContext) in
// Get again NSManagedObject in correct context,
// original self.task persists in main context
let backTask = backgroundContext.objectWithID(self.task.objectID) as! CTask
backTask.completed = true
let _ = try? backgroundContext.save()
})
NSFetchedResultsController doesn’t update cells. I will see updated data if I reload application or whole view for example.
There is no error in data saving (I’ve checked).
I’ve tried to check NSManagedObjectContextDidSaveNotification is received, but if I do .performFetch() after notification is received I again get old data in table.
I’ve created a ticket at Stackoverflow, I’ve got reply that backgroundContext doesn’t merge changes with mainContext.
Where would I init with the proper dictionary?
[NSMigratePersistentStoresAutomaticallyOption: true,
NSInferMappingModelAutomaticallyOption: true]
When i run the DemoSwift app, then tap on bar button on the top left, new data being created. Then i quit the app (rebuild/force quit), the data disappear, althought all data from background is stored. Am i missing some thing? Or it is a bug?
When mergeChangesFromContextDidSaveNotification
happens with non faulted objects _newChangedValuesForRefresh__
gets called to fault the objects before merging them, this could be happening on the main thread so it could help to do the following loop in order to bring faulted objects before performing the merge.
NSArray* objects = [notification.userInfo valueForKey:NSUpdatedObjectsKey];
for (NSManagedObject* obj in objects) {
NSManagedObject* mainThreadObject = [mainContext objectWithID:obj.objectID];
[mainThreadObject willAccessValueForKey:nil];
}
Add fetch helpers
Crashed: com.apple.main-thread
0 CoreFoundation 0x181c93070 -[NSSetM addObject:] + 476
1 CoreFoundation 0x181c8db00 -[NSMutableSet unionSet:] + 776
2 CoreData 0x183ca895c -[NSManagedObjectContext _mergeChangesFromDidSaveDictionary:usingObjectIDs:] + 3144
3 CoreData 0x183ca8c20 -[NSManagedObjectContext mergeChangesFromContextDidSaveNotification:] + 500
4 DATAStack 0x10049e250 TPA__TFFC9DATAStack9DATAStack24backgroundContextDidSaveFzCSo14NSNotificationT_U_FT_T + 132
5 CoreData 0x183ca908c developerSubmittedBlockToNSManagedObjectContextPerform + 196
6 libdispatch.dylib 0x1817f547c _dispatch_client_callout + 16
7 libdispatch.dylib 0x1817fab84 _dispatch_main_queue_callback_4CF + 1844
8 CoreFoundation 0x181d60dd8 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE + 12
9 CoreFoundation 0x181d5ec40 __CFRunLoopRun + 1628
10 CoreFoundation 0x181c88d10 CFRunLoopRunSpecific + 384
11 GraphicsServices 0x183570088 GSEventRunModal + 180
12 UIKit 0x186f55f70 UIApplicationMain + 204
When I run app in production I don't want the code to run "Is it UnitTest target" all the time.
The solution would be co create a separate subclass for DATAStack, that would override those methods and do them in sync way.
Throws from notifications is very hard to debug -- XCode 8 doesn't show exact place where exception was raised, you see only EXC_BAD_ACCESS.
Example throw:
func backgroundContextDidSave(notification: NSNotification) throws {
if NSThread.isMainThread() && TestCheck.isTesting == false {
throw NSError(info: "Background context saved in the main thread. Use context's `performBlock`", previousError: nil)
My main goal is to give an ability to developer to catch a bug with correct error message and full method call history (throw won't give call stack correctly).
I don't know if throw from notification will crash binary on release build, on debug build it crashes.
My proposals:
throws
to asserts
, so you can see error message, exact place and correct view in debugger. Assert will be shown only on debug build, so in release mode application will try continue work without guarantees, may be Core Data won't raise an exception and all will be okay.throws
to fatalErrors
, so application will terminate in any way in release & debug mode.When my app has problems migrating the data or adding the persistent store with type SQLite, then I get an error that I don't have a way to handle.
For example, in my app I only download new data when new data is available, I have a request for that, but when the migration fails all my data gets removed and I don't know that I have to request new data. It would be great if I was notified or had a way to handle those things.
Actual error:
2016-05-20 09:58:47.594 iOS Development[1306:355137] CoreData: error: -addPersistentStoreWithType:SQLite configuration:(null) URL:file:///var/mobile/Containers/Data/Application/605954E3-1C3C-490C-8D98-F9F9FFD61721/Documents/Project.sqlite options:{
NSInferMappingModelAutomaticallyOption = 1;
NSMigratePersistentStoresAutomaticallyOption = 1;
} ... returned error Error Domain=NSCocoaErrorDomain Code=134110 "An error occurred during persistent store migration." UserInfo={sourceURL=file:///var/mobile/Containers/Data/Application/605954E3-1C3C-490C-8D98-F9F9FFD61721/Documents/Project.sqlite, reason=Cannot migrate store in-place: Validation error missing attribute values on mandatory destination attribute, destinationURL=file:///var/mobile/Containers/Data/Application/605954E3-1C3C-490C-8D98-F9F9FFD61721/Documents/.Project.sqlite.migrationdestination_41b5a6b5c6e848c462a8480cd24caef3, NSUnderlyingError=0x12e28b250 {Error Domain=NSCocoaErrorDomain Code=134110 "An error occurred during persistent store migration." UserInfo={entity=Album, attribute=id, reason=Validation error missing attribute values on mandatory destination attribute}}} with userInfo dictionary {
NSUnderlyingError = "Error Domain=NSCocoaErrorDomain Code=134110 \"An error occurred during persistent store migration.\" UserInfo={entity=Album, attribute=id, reason=Validation error missing attribute values on mandatory destination attribute}";
destinationURL = "file:///var/mobile/Containers/Data/Application/605954E3-1C3C-490C-8D98-F9F9FFD61721/Documents/.Project.sqlite.migrationdestination_41b5a6b5c6e848c462a8480cd24caef3";
reason = "Cannot migrate store in-place: Validation error missing attribute values on mandatory destination attribute";
sourceURL = "file:///var/mobile/Containers/Data/Application/605954E3-1C3C-490C-8D98-F9F9FFD61721/Documents/Project.sqlite";
}
I use DATASource for showing large (~50000 rows) data set and using DATAStack.mainContext in NSFRC.
When I set request.fetchBatchSize for optimizing memory usage purposes it is ignored somehow. And all 50000 rows loads into memory.
I research for the issue a little bit and found that there is an issue in Core Data when stack configured with usage of nested contexts. - http://openradar.appspot.com/11235622. Also here is what I found on StackOverflow
May be some workaround can be implemented in DATAStack for partially resolve the described issue.
For example, DATAStack could provide so called newMainContext() method that should return context that have NSMainQueueConcurencyType and directly linked to Persistent Store Coordinator.
Another possible solution (not sure about that): try to use background context in NSFRC that newBackgroundContext() method can return. But in this case this context should be notified about changes in persistent store that have been done in another background context and merge them for update table in UI.
Have you any thoughts about that?
Thank you
Hi!
The method: performInNewBackgroundContext: is missing a parameter name in the completion block.
//The method is declared like this in the current bridging header:
[self.dataStack performInNewBackgroundContext:^(NSManagedObjectContext * _Nonnull) {
<#code#>
}];
//It should be declared like this:
[self.dataStack performInNewBackgroundContext:^(NSManagedObjectContext * _Nonnull backgroundContext) {
<#code#>
}];
Hey @3lvis, do you intent do add Swift 4 support? Happy to help if necessary.
Hi 3lvis,
Recently upgraded our project to swift 4 and 8.0 if datastack and everything is fine. However when i go to build the project on travis i get the following errors:
/Pods/Sync/Source/DataStack/DataStack.swift:42:64: argument of '#selector' refers to instance method 'mainContextDidSave' that is not exposed to Objective-C
NotificationCenter.default.addObserver(self, selector: #selector(DataStack.mainContextDidSave(_:)), name: .NSManagedObjectContextDidSave, object: context)
/Pods/Sync/Source/DataStack/DataStack.swift:213:64: argument of '#selector' refers to instance method 'newDisposableMainContextWillSave' that is not exposed to Objective-C
NotificationCenter.default.addObserver(self, selector: #selector(DataStack.newDisposableMainContextWillSave(_:)), name: NSNotification.Name.NSManagedObjectContextWillSave, object: context)
and...
/Pods/Sync/Source/DataStack/DataStack.swift:241:64: argument of '#selector' refers to instance method 'backgroundContextDidSave' that is not exposed to Objective-C
NotificationCenter.default.addObserver(self, selector: #selector(DataStack.backgroundContextDidSave(_:)), name: .NSManagedObjectContextDidSave, object: context)
It seems as if the swift 3 @obj inference is being taken into travis as its pulled from cocopods. Im looking into it but do you see these errors on travis ?
How I can know when data which was save in background is ready for use in main context (thread)?
Hi I've got the following model (for example)
Then in my controller i define the data stack like this:
let coreData = DATAStack(modelName: "Test", storeType: .sqLite)
Later I'd like to do a count on the Product entity like this:
do {
let productCount = try coreData.viewContext.count(for: Product.fetchRequest())
debugPrint("product Count in coredata: \(productCount)")
}
catch let e {
debugPrint(e.localizedDescription)
}
That works as expected!
Now I'd like to do some kind of archive with the exact same model. So what I did is to just create another instance with the same model like this:
let archive = DATAStack(modelName: "Test", bundle: Bundle.main, storeType: .sqLite, storeName: "Test-Archive", containerURL: FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last!)
After that the productCount will not work anymore and the app crashes with the following message:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '_countWithNoChangesForRequest:error: A fetch request must have an entity.
Here is the whole code to reproduce this behaviour:
import UIKit
import DATAStack
class ViewController: UIViewController {
let coreData = DATAStack(modelName: "Test", storeType: .sqLite)
let archive = DATAStack(modelName: "Test", bundle: Bundle.main, storeType: .sqLite, storeName: "Test-Archive", containerURL: FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last!)
override func viewDidLoad() {
super.viewDidLoad()
debugPrint("coreData located at: \(coreData.viewContext.persistentStoreCoordinator!.persistentStores.first!.url!.absoluteString)")
debugPrint("archive located at: \(archive.viewContext.persistentStoreCoordinator!.persistentStores.first!.url!.absoluteString)")
do {
let productCount = try coreData.viewContext.count(for: Product.fetchRequest())
debugPrint("product Count in coredata: \(productCount)")
}
catch let e {
debugPrint(e.localizedDescription)
}
}
}
Can anyone help me with this one? How can I approach this?
Thx
It basically comes down to these three option values that need to be added to the array of options when creating the PersistentStore.
https://github.com/3lvis/DATAStack/blob/master/Source/DATAStack.swift#L113
https://github.com/3lvis/DATAStack/blob/master/Source/DATAStack.swift#L105
NSExternalRecordExtensionOption // File extension
NSExternalRecordsDirectoryOption // Directory
NSExternalRecordsFileFormatOption // NSBinaryExternalRecordType
In addition to that we need to ensure that the folder exists. So something like this should do the trick.
NSString *externalRecordsSupportFolder = [@"~/Library/Caches/Metadata/CoreData/$ProjectName$/" stringByExpandingTildeInPath];
[fileManager createDirectoryAtPath:externalRecordsSupportFolder withIntermediateDirectories:YES attributes:nil error:&error];
What do you think about this?
Hello! Is it the way to create new context, that can be used in main thread in DATAStack? For example I have «Edit item» view, I load all data there in separate context and if user doesn’t click «Save» all changes in that separate context are reset.
I’ve found only way to create separate background context (newBackgroundContext
), or create newDisposableMainContext
, but it is detached from saving to disk, so I can’t merge changes in it to my default mainContext.
I am facing an issue where operations against the dataStack.mainContext are not effective; for example,
print(dataStack.mainContext.hasChanges) // true
try! dataStack.mainContext.save()
print(dataStack.mainContext.hasChanges) // false
However, when the application reloads, the changes have not been committed to disk (reloading the database programmatically "works", but application restart does not.)
Simply changing to performInNewBackgroundContext{} makes everything work.
What might be the cause?
NSmananagedObjectContext use dispatchQueues, and they are not the same as threads.
I can make completely correct code which will show that i did smt wrong.
Example.
NSManagedObjectContext *context = [ANDYDataManager backgroundContext];
[context performBlockAndWait:^{
[context save:nil]
}];
If I run this code on main thread, it will show me an error, because performBlockAndWait
is performed on the same thread
it's better to turn on CoreData environment variable to check correct multithread usage
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.