├── .gitignore
├── .idea
├── .name
├── CoreDataEnvir.iml
├── encodings.xml
├── misc.xml
├── modules.xml
├── scopes
│ └── scope_settings.xml
├── vcs.xml
├── workspace.xml
└── xcode.xml
├── .travis.yml
├── CoreDataEnvir.podspec
├── CoreDataEnvir
├── CoreDataEnvirHeader.h
└── Info.plist
├── CoreDataEnvirSample.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── CoreDataEnvirSample.xccheckout
│ │ └── IDEWorkspaceChecks.plist
└── xcshareddata
│ └── xcschemes
│ ├── CoreDataEnvir.xcscheme
│ └── CoreDataEnvirSampleTests.xcscheme
├── CoreDataEnvirSample.xcworkspace
├── contents.xcworkspacedata
└── xcshareddata
│ └── IDEWorkspaceChecks.plist
├── CoreDataEnvirSample
├── AppDelegate.h
├── AppDelegate.m
├── ConcurrencyViewController.h
├── ConcurrencyViewController.m
├── CoreDataEnvirSample-Bridging-Header.h
├── RelationshipViewController.h
├── RelationshipViewController.m
├── Supporting Files
│ ├── CoreDataEnvirSample-Info.plist
│ ├── CoreDataEnvirSample-Prefix.pch
│ ├── Default-568h@2x.png
│ ├── Default.png
│ ├── Default@2x.png
│ ├── Member.h
│ ├── Member.m
│ ├── SampleModel.xcdatamodeld
│ │ └── SampleModel.xcdatamodel
│ │ │ └── contents
│ ├── Team.h
│ ├── Team.m
│ ├── demo.plist
│ ├── en.lproj
│ │ └── InfoPlist.strings
│ └── main.m
├── SwiftViewController.swift
├── ViewController.h
├── ViewController.m
└── zh-Hans.lproj
│ └── InfoPlist.strings
├── CoreDataEnvirSampleTests
├── CoreDataEnvirTests.m
└── Supporting Files
│ ├── CoreDataEnvirSampleTests-Info.plist
│ ├── en.lproj
│ └── InfoPlist.strings
│ └── zh-Hans.lproj
│ └── InfoPlist.strings
├── CoreDataEnvirTests
├── CoreDataEnvirTests.m
└── Info.plist
├── LICENSE
├── Member+CoreDataClass.swift
├── Member+CoreDataProperties.swift
├── ObjcUML
├── Scripts
│ ├── d3.v3.js
│ ├── d3.v3.min.js
│ ├── d3js-LICENSE
│ └── parse.js
├── dependency.css
├── index.html
└── origin.js
├── Podfile
├── Podfile.lock
├── Pods
├── Local Podspecs
│ └── CoreDataEnvir.podspec.json
├── Manifest.lock
├── Pods.xcodeproj
│ ├── project.pbxproj
│ └── xcuserdata
│ │ └── dehengxu.xcuserdatad
│ │ └── xcschemes
│ │ ├── CoreDataEnvir.xcscheme
│ │ ├── Pods-CoreDataEnvirSample.xcscheme
│ │ ├── Pods-CoreDataEnvirSampleTests.xcscheme
│ │ └── xcschememanagement.plist
└── Target Support Files
│ ├── CoreDataEnvir
│ ├── CoreDataEnvir-Info.plist
│ ├── CoreDataEnvir-dummy.m
│ ├── CoreDataEnvir-prefix.pch
│ ├── CoreDataEnvir-umbrella.h
│ ├── CoreDataEnvir.debug.xcconfig
│ ├── CoreDataEnvir.modulemap
│ └── CoreDataEnvir.release.xcconfig
│ ├── Pods-CoreDataEnvirSample
│ ├── Pods-CoreDataEnvirSample-Info.plist
│ ├── Pods-CoreDataEnvirSample-acknowledgements.markdown
│ ├── Pods-CoreDataEnvirSample-acknowledgements.plist
│ ├── Pods-CoreDataEnvirSample-dummy.m
│ ├── Pods-CoreDataEnvirSample-frameworks-Debug-input-files.xcfilelist
│ ├── Pods-CoreDataEnvirSample-frameworks-Debug-output-files.xcfilelist
│ ├── Pods-CoreDataEnvirSample-frameworks-Release-input-files.xcfilelist
│ ├── Pods-CoreDataEnvirSample-frameworks-Release-output-files.xcfilelist
│ ├── Pods-CoreDataEnvirSample-frameworks.sh
│ ├── Pods-CoreDataEnvirSample-umbrella.h
│ ├── Pods-CoreDataEnvirSample.debug.xcconfig
│ ├── Pods-CoreDataEnvirSample.modulemap
│ └── Pods-CoreDataEnvirSample.release.xcconfig
│ └── Pods-CoreDataEnvirSampleTests
│ ├── Pods-CoreDataEnvirSampleTests-Info.plist
│ ├── Pods-CoreDataEnvirSampleTests-acknowledgements.markdown
│ ├── Pods-CoreDataEnvirSampleTests-acknowledgements.plist
│ ├── Pods-CoreDataEnvirSampleTests-dummy.m
│ ├── Pods-CoreDataEnvirSampleTests-umbrella.h
│ ├── Pods-CoreDataEnvirSampleTests.debug.xcconfig
│ ├── Pods-CoreDataEnvirSampleTests.modulemap
│ └── Pods-CoreDataEnvirSampleTests.release.xcconfig
├── README.md
├── README_zh.md
├── Team+CoreDataClass.swift
├── Team+CoreDataProperties.swift
├── backup.sh
├── build.sh
├── check
├── podupdate.sh
├── push2pods
├── pushtag
├── src
└── CoreDataEnvir
│ ├── CoreDataEnvir.h
│ ├── CoreDataEnvir.m
│ ├── CoreDataEnvirDescriptor.h
│ ├── CoreDataEnvirDescriptor.m
│ ├── CoreDataEnvirHeader.h
│ ├── CoreDataEnvirObserver.h
│ ├── CoreDataEnvir_Background.h
│ ├── CoreDataEnvir_Background.m
│ ├── CoreDataEnvir_Main.h
│ ├── CoreDataEnvir_Main.m
│ ├── CoreDataRescureDelegate.h
│ ├── ManagedObject
│ ├── NSManagedObject_Background.h
│ ├── NSManagedObject_Background.m
│ ├── NSManagedObject_Convenient.h
│ ├── NSManagedObject_Convenient.m
│ ├── NSManagedObject_MainThread.h
│ └── NSManagedObject_MainThread.m
│ └── Private
│ ├── CoreDataEnvir_Private.h
│ └── CoreDataEnvir_Private.m
└── syncgit
/.gitignore:
--------------------------------------------------------------------------------
1 | ObjcUML/
2 | xcuserdata/
3 | build/
4 |
--------------------------------------------------------------------------------
/.idea/.name:
--------------------------------------------------------------------------------
1 | CoreDataEnvirSample
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/scopes/scope_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/xcode.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | osx_image: xcode6.4
2 | language: objective-c
3 | xcode_project: CoreDataEnvirSample.xcodeproj
4 | xcode_scheme: CoreDataEnvirSampleTests
5 |
--------------------------------------------------------------------------------
/CoreDataEnvir.podspec:
--------------------------------------------------------------------------------
1 | #
2 | # Be sure to run `pod spec lint CoreDataEnvir.podspec' to ensure this is a
3 | # valid spec and to remove all comments including this before submitting the spec.
4 | #
5 | # To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html
6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/
7 | #
8 |
9 | Pod::Spec.new do |s|
10 |
11 | # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
12 | #
13 | # These will help people to find your library, and whilst it
14 | # can feel like a chore to fill in it's definitely to your advantage. The
15 | # summary should be tweet-length, and the description more in depth.
16 | #
17 |
18 | s.name = "CoreDataEnvir"
19 | s.version = "0.13.0-beta.1"
20 | s.summary = "CoreDataEnvir is a CoreData wrapper which use CoreData in convient way and supply thread safe in concurrenct programming."
21 |
22 | s.description = <<-DESC
23 | CoreDataEnvir is a CoreData wrapper which use CoreData in convient way and supply thread safe in concurrenct programming. You can use it concurrenctly,run seperate CoreDataEnvir instance on one thread.
24 | DESC
25 |
26 | s.homepage = "https://dehengxu.github.io/CoreDataEnvir"
27 | # s.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif"
28 | s.module_name = "CoreDataEnvir"
29 |
30 | # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
31 | #
32 | # Licensing your code is important. See http://choosealicense.com for more info.
33 | # CocoaPods will detect a license file if there is a named LICENSE*
34 | # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'.
35 | #
36 |
37 | s.license = "MIT"
38 | # s.license = { :type => "MIT", :file => "FILE_LICENSE" }
39 |
40 |
41 | # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
42 | #
43 | # Specify the authors of the library, with email addresses. Email addresses
44 | # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also
45 | # accepts just a name if you'd rather not provide an email address.
46 | #
47 | # Specify a social_media_url where others can refer to, for example a twitter
48 | # profile URL.
49 | #
50 |
51 | s.author = { "DehengXu" => "dehengxu@outlook.com" }
52 | # Or just: s.author = "CyberLion"
53 | # s.authors = { "CyberLion" => "dehengxu@outlook.com" }
54 | s.social_media_url = "https://github.com/dehengxu"
55 |
56 | # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
57 | #
58 | # If this Pod runs only on iOS or OS X, then specify the platform and
59 | # the deployment target. You can optionally include the target after the platform.
60 | #
61 |
62 | s.platform = :ios, '10.0'
63 | # s.platform = :ios, "5.0"
64 |
65 | # When using multiple platforms
66 | # s.ios.deployment_target = "5.0"
67 | # s.osx.deployment_target = "10.7"
68 |
69 |
70 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
71 | #
72 | # Specify the location from where the source should be retrieved.
73 | # Supports git, hg, bzr, svn and HTTP.
74 | #
75 |
76 | s.source = { :git => "https://github.com/dehengxu/CoreDataEnvir.git", :tag => s.version }
77 |
78 |
79 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
80 | #
81 | # CocoaPods is smart about how it includes source code. For source files
82 | # giving a folder will include any h, m, mm, c & cpp files. For header
83 | # files it will include any header in the folder.
84 | # Not including the public_header_files will make all headers public.
85 | #
86 |
87 | s.source_files = "src/CoreDataEnvir/*.h", "src/CoreDataEnvir/**/*.{h,m}"
88 | # s.exclude_files = "CoreDataEnvir/Debug"
89 |
90 | s.public_header_files = "src/CoreDataEnvir/**/*.h" #, "src/CoreDataEnvir/*.h"
91 |
92 |
93 | # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
94 | #
95 | # A list of resources included with the Pod. These are copied into the
96 | # target bundle with a build phase script. Anything else will be cleaned.
97 | # You can preserve files from being cleaned, please don't preserve
98 | # non-essential files like tests, examples and documentation.
99 | #
100 |
101 | # s.resource = "icon.png"
102 | # s.resources = "Resources/*.png"
103 |
104 | # s.preserve_paths = "FilesToSave", "MoreFilesToSave"
105 |
106 |
107 | # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
108 | #
109 | # Link your library with frameworks, or libraries. Libraries do not include
110 | # the lib prefix of their name.
111 | #
112 |
113 | # s.framework = "CoreData"
114 | s.frameworks = "CoreData"#, "AnotherFramework"
115 |
116 | # s.library = "iconv"
117 | # s.libraries = "iconv", "xml2"
118 |
119 |
120 | # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
121 | #
122 | # If your library depends on compiler flags you can set them in the xcconfig hash
123 | # where they will only apply to your library. If you depend on other Podspecs
124 | # you can include multiple dependencies to ensure it works.
125 |
126 | s.requires_arc = true
127 | s.info_plist = {
128 | "CFBundleIdentifier"=>"com.dehengxu.CoreDataEnvir"
129 | }
130 | # s.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" }
131 | # s.dependency "JSONKit", "~> 1.4"
132 |
133 | end
134 |
--------------------------------------------------------------------------------
/CoreDataEnvir/CoreDataEnvirHeader.h:
--------------------------------------------------------------------------------
1 | //
2 | // CoreDataEnvirHeader.h
3 | // CoreDataEnvirSample
4 | //
5 | // Created by NicholasXu on 15/8/30.
6 | // Copyright (c) 2015年 Nicholas.Xu. All rights reserved.
7 | //
8 |
9 | //#ifndef CoreDataEnvirSample_CoreDataEnvirHeader_h
10 | //#define CoreDataEnvirSample_CoreDataEnvirHeader_h
11 |
12 | #import "CoreDataEnvir.h"
13 | #import "CoreDataEnvir_Main.h"
14 | #import "CoreDataEnvir_Background.h"
15 |
16 | #import "NSManagedObject_Convenient.h"
17 | #import "NSManagedObject_MainThread.h"
18 | #import "NSManagedObject_Background.h"
19 | #if __has_include("NSObject_Debug.h")
20 | #import "NSObject_Debug.h"
21 | #endif
22 |
23 | //! Project version number for CoreDataEnvir.
24 | FOUNDATION_EXPORT double CoreDataEnvirVersionNumber;
25 |
26 | //! Project version string for CoreDataEnvir.
27 | FOUNDATION_EXPORT const unsigned char CoreDataEnvirVersionString[];
28 |
29 | //#endif
30 |
--------------------------------------------------------------------------------
/CoreDataEnvir/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 |
22 |
23 |
--------------------------------------------------------------------------------
/CoreDataEnvirSample.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/CoreDataEnvirSample.xcodeproj/project.xcworkspace/xcshareddata/CoreDataEnvirSample.xccheckout:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDESourceControlProjectFavoriteDictionaryKey
6 |
7 | IDESourceControlProjectIdentifier
8 | 6B39E785-E4A3-4D88-944D-A0CB7355FC94
9 | IDESourceControlProjectName
10 | CoreDataEnvirSample
11 | IDESourceControlProjectOriginsDictionary
12 |
13 | 0625EBF42F455C9F64085466B99E788FF87C770A
14 | bitbucket.org:xudeheng/CoreDataEnvir.git
15 |
16 | IDESourceControlProjectPath
17 | CoreDataEnvirSample.xcodeproj
18 | IDESourceControlProjectRelativeInstallPathDictionary
19 |
20 | 0625EBF42F455C9F64085466B99E788FF87C770A
21 | ../..
22 |
23 | IDESourceControlProjectURL
24 | bitbucket.org:xudeheng/CoreDataEnvir.git
25 | IDESourceControlProjectVersion
26 | 111
27 | IDESourceControlProjectWCCIdentifier
28 | 0625EBF42F455C9F64085466B99E788FF87C770A
29 | IDESourceControlProjectWCConfigurations
30 |
31 |
32 | IDESourceControlRepositoryExtensionIdentifierKey
33 | public.vcs.git
34 | IDESourceControlWCCIdentifierKey
35 | 0625EBF42F455C9F64085466B99E788FF87C770A
36 | IDESourceControlWCCName
37 | CoreDataEnvir
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/CoreDataEnvirSample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/CoreDataEnvirSample.xcodeproj/xcshareddata/xcschemes/CoreDataEnvir.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
44 |
50 |
51 |
57 |
58 |
59 |
60 |
62 |
63 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/CoreDataEnvirSample.xcodeproj/xcshareddata/xcschemes/CoreDataEnvirSampleTests.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
14 |
15 |
17 |
23 |
24 |
25 |
26 |
27 |
37 |
38 |
44 |
45 |
47 |
48 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/CoreDataEnvirSample.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
12 |
13 |
15 |
16 |
18 |
19 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/CoreDataEnvirSample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/CoreDataEnvirSample/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // CoreDataEnvirSample
4 | //
5 | // Created by Deheng.Xu on 13-4-7.
6 | // Copyright (c) 2013年 Nicholas.Xu. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @class ViewController;
12 |
13 | @interface AppDelegate : UIResponder
14 |
15 | @property (strong, nonatomic) UIWindow *window;
16 |
17 | @property (strong, nonatomic) ViewController *viewController;
18 | @property (strong, nonatomic) UINavigationController *navigationController;
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/CoreDataEnvirSample/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // CoreDataEnvirSample
4 | //
5 | // Created by Deheng.Xu on 13-4-7.
6 | // Copyright (c) 2013年 Nicholas.Xu. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | #import "ViewController.h"
12 |
13 | #import "CoreDataEnvir.h"
14 | #import "Team.h"
15 | #import "Member.h"
16 | #import
17 |
18 | _Bool checkEnv(const char* name) {
19 | const char* env = getenv(name);
20 | return (env != 0 && strcmp(env, "1") == 0);
21 | }
22 |
23 | @implementation AppDelegate
24 |
25 | - (void)dealloc
26 | {
27 | }
28 |
29 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
30 | {
31 | if (!checkEnv("debug")) {
32 | exit(0);
33 | }
34 | if (!checkEnv("demo")) {
35 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
36 | self.window.rootViewController = [UIViewController new];
37 | self.window.rootViewController.view.backgroundColor = UIColor.blackColor;
38 | [self.window makeKeyAndVisible];
39 | #if true // test legacy
40 | // [CoreDataEnvir.backgroundInstance asyncWithBlock:^(CoreDataEnvir * _Nonnull db) {
41 | // [Team insertItemInContext:db fillData:^(Team* _Nonnull item) {
42 | // item.name = @"CybLion";
43 | // }];
44 | // [db saveDataBase];
45 | // }];
46 |
47 | // [Team insertItemOnBackgroundWithFillingBlock:^(Team* _Nonnull item) {
48 | // item.name = @"Lion";
49 | // }];
50 |
51 | // [Team insertItemWithFillingBlock:^(Team* item) {
52 | // item.name = @"Lion";
53 | // [item save];
54 | // }];
55 |
56 | CoreDataEnvir* db = [CoreDataEnvirDescriptor.defaultInstance backgroundInstance];
57 | [Team insertItemInContext:db];
58 | [db saveDataBase];
59 | printf("Team total count: %lu\n", Team.totalCount);
60 | #else
61 | NSURL* modelURL = [NSBundle.mainBundle URLForResource:@"SampleModel" withExtension:@"momd"];
62 | CoreDataEnvirBlock initBlock = ^(CoreDataEnvir* db) {
63 | [db setupModelWithURL:modelURL];
64 |
65 | NSString* searchedPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true) lastObject];
66 | NSLog(@"search path: %@", searchedPath);
67 | NSURL* dbURL = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/db.sqlite", searchedPath]];
68 | NSLog(@"dbURL: %@", dbURL);
69 | if (dbURL) {
70 | [db setupDefaultPersistentStoreWithURL:dbURL];
71 | }
72 | };
73 | CoreDataEnvir* db = [CoreDataEnvir create];
74 | [db setupWithBlock:initBlock];
75 | CoreDataEnvir* db2 = [CoreDataEnvir create];
76 | [db2 setupWithBlock:initBlock];
77 |
78 | [db syncInBlock:^(CoreDataEnvir * _Nonnull db) {
79 | Team* obj = [Team insertItemInContext:db];
80 | obj.name = @"new pattern";
81 | [db saveDataBase];
82 |
83 | NSFetchRequest* req = [Team newFetchRequestInContext:db];
84 | NSError* err = nil;
85 | NSUInteger count = [db.context countForFetchRequest:req error:&err];
86 | printf("Team total count: %lu\n", count);
87 | }];
88 |
89 | #endif
90 | return true;
91 | }
92 | NSLog(@"CoreDataEnvirVersionString: %s", CoreDataEnvirVersionString);
93 | NSLog(@"CoreDataEnvirVersionNumber: %f", CoreDataEnvirVersionNumber);
94 | //Set db file name and model file name.
95 | // [CoreDataEnvir registerDefaultDataFileName:@"db.sqlite"];
96 | // [CoreDataEnvir registerDefaultModelFileName:@"SampleModel"];
97 |
98 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
99 | // Override point for customization after application launch.
100 | self.viewController = [[ViewController alloc] initWithNibName:nil bundle:nil];
101 | self.navigationController = [[UINavigationController alloc] initWithRootViewController:self.viewController];
102 |
103 | //NSLog(@"ver: %f", CoreDataEnvirVersionNumber);
104 |
105 | self.window.rootViewController = self.navigationController;
106 | [self.window makeKeyAndVisible];
107 |
108 | return YES;
109 | }
110 |
111 | - (void)applicationWillResignActive:(UIApplication *)application
112 | {
113 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
114 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
115 | }
116 |
117 | - (void)applicationDidEnterBackground:(UIApplication *)application
118 | {
119 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
120 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
121 | }
122 |
123 | - (void)applicationWillEnterForeground:(UIApplication *)application
124 | {
125 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
126 | }
127 |
128 | - (void)applicationDidBecomeActive:(UIApplication *)application
129 | {
130 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
131 | }
132 |
133 | - (void)applicationWillTerminate:(UIApplication *)application
134 | {
135 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
136 | }
137 |
138 | @end
139 |
--------------------------------------------------------------------------------
/CoreDataEnvirSample/ConcurrencyViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ConcurrencyViewController.h
3 | // CoreDataEnvirSample
4 | //
5 | // Created by Deheng.Xu on 13-9-26.
6 | // Copyright (c) 2013年 Nicholas.Xu. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "CoreDataEnvir.h"
11 | #import "CoreDataEnvirHeader.h"
12 |
13 | @class Team;
14 | @class Member;
15 |
16 | @interface ConcurrencyViewController : UIViewController
17 | <
18 | CoreDataRescureDelegate
19 | >
20 | {
21 | dispatch_semaphore_t __runs_sema;
22 | }
23 |
24 | @property (nonatomic, strong) Team *teamOnMainThread;
25 | @property (nonatomic, strong) Team *teamOnBackground;
26 |
27 | - (IBAction)onClick_test:(id)sender;
28 | - (IBAction)onClick_clearAll:(id)sender;
29 | - (IBAction)onClick_look:(id)sender;
30 |
31 | @end
32 |
--------------------------------------------------------------------------------
/CoreDataEnvirSample/ConcurrencyViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ConcurrencyViewController.m
3 | // CoreDataEnvirSample
4 | //
5 | // Created by Deheng.Xu on 13-9-26.
6 | // Copyright (c) 2013年 Nicholas.Xu. All rights reserved.
7 | //
8 |
9 | #import "ConcurrencyViewController.h"
10 |
11 | #import
12 | #import
13 |
14 | //#import
15 | @import CoreDataEnvir;
16 | #import "Team.h"
17 | #import "Member.h"
18 |
19 | #define THREAD_NUMBER 1
20 | #define LOOP_NUMBER_PER_THREAD 1024 * 2
21 |
22 | //Test concurrency.
23 | #define TESTING_A 1
24 |
25 | #define TESTING_B 2
26 | //Test creating mutch number of instance.
27 | #define TESTING_C 3
28 | //Test IO stream.
29 | #define TESTING_D 4
30 |
31 | #define testing_case TESTING_A
32 |
33 | @interface ConcurrencyViewController ()
34 |
35 | @end
36 |
37 | @implementation ConcurrencyViewController
38 |
39 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
40 | {
41 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
42 | if (self) {
43 | // Custom initialization
44 | __runs_sema = dispatch_semaphore_create(1l);
45 | }
46 | return self;
47 | }
48 |
49 | - (void)dealloc
50 | {
51 | }
52 |
53 | - (void)viewDidLoad
54 | {
55 | [super viewDidLoad];
56 | // Do any additional setup after loading the view.
57 | self.view.backgroundColor = [UIColor lightGrayColor];
58 |
59 | NSString * actions[3] = {@"onClick_test:", @"onClick_clearAll:", @"onClick_look:"};
60 | NSString * titles[3] = {@"Test Concurrency", @"Clear DB", @"Watch"};
61 |
62 | CGSize buttonSize = CGSizeMake(180, 60);
63 |
64 | for (int i = 0; i < 3; i++) {
65 |
66 | UIButton *btn = [[UIButton alloc] initWithFrame:CGRectZero];
67 | btn.frame = CGRectMake(20, 20 + self.navigationController.navigationBar.frame.size.height + i * buttonSize.height, buttonSize.width, buttonSize.height);
68 | [btn addTarget:self action:NSSelectorFromString(actions[i]) forControlEvents:UIControlEventTouchUpInside];
69 | [btn setTitle:titles[i] forState:UIControlStateNormal];
70 | [self.view addSubview:btn];
71 |
72 | }
73 | }
74 |
75 | - (void)viewWillAppear:(BOOL)animated
76 | {
77 | [super viewWillAppear:animated];
78 | }
79 |
80 | - (void)viewWillDisappear:(BOOL)animated
81 | {
82 | [super viewWillDisappear:animated];
83 | }
84 |
85 | - (void)didReceiveMemoryWarning
86 | {
87 | [super didReceiveMemoryWarning];
88 | // Dispose of any resources that can be recreated.
89 | }
90 |
91 | int runs_forever = THREAD_NUMBER;
92 | - (void)updateDatabaseOnMainThread
93 | {
94 | dispatch_async(dispatch_get_main_queue(), ^{
95 | CoreDataEnvir *db = [CoreDataEnvir instance];
96 | short testCounter = 0;
97 | NSLog(@"Start updating...");
98 | while (runs_forever && testCounter >= 0) {
99 | testCounter ++;
100 | Team *team = [Team lastItemInContext:db usingPredicate:[NSPredicate predicateWithFormat:@"name==%@", @"com.cyblion"]];
101 | team.number = @(testCounter);
102 | [db saveDataBase];
103 | printf("update to \"%hd\".\n", testCounter);
104 | }
105 | NSLog(@"Stoped updating.");
106 | });
107 |
108 | }
109 |
110 | - (void)runTestA:(dispatch_queue_t)queue withTimes:(unsigned int)times
111 | {
112 | //Every thread runs 101 times Request operation.
113 | int runTimes = times;
114 | dispatch_async(queue, ^{
115 | CoreDataEnvir *db = [CoreDataEnvir instance];
116 | [CoreDataEnvir setRescureDelegate:self];
117 |
118 | NSString *queueLabel = [NSString stringWithCString:dispatch_queue_get_label(queue) encoding:NSUTF8StringEncoding];
119 |
120 | if (!self.teamOnBackground) {
121 | self.teamOnBackground = [Team lastItemInContext:db];
122 | }
123 | //Team *t = [Team lastItemInContext:db];
124 |
125 | //for (int i = t.number.intValue; i < runTimes; i++) {
126 | int i = 0;
127 | for (;;) {
128 | Team *team = (Team *)[Team lastItemInContext:db];
129 |
130 | i = team.number.intValue;
131 | i ++;
132 |
133 | if (team) {
134 | team.number = @(i);
135 | }else {
136 | team = [Team insertItemInContext:db fillData:^(Team *item) {
137 | item.name = queueLabel;
138 | item.number = @(0);
139 | }];
140 | }
141 | [team saveTo:db];
142 |
143 | if (team) {
144 | NSLog(@"testing queue :%@; team.number :%@", queueLabel, self.teamOnBackground.number);
145 | }
146 |
147 | if (i >= runTimes - 1) {
148 | //i = 0;
149 | break;
150 | }
151 |
152 | [NSThread sleepForTimeInterval:0.05];
153 | }
154 | dispatch_semaphore_wait(self->__runs_sema, ~0ull);
155 | runs_forever--;
156 | dispatch_semaphore_signal(self->__runs_sema);
157 | NSLog(@"runs_forever :%d", runs_forever);
158 | });
159 | }
160 |
161 | - (void)runTestB:(dispatch_queue_t)queue withTimes:(unsigned int)times
162 | {
163 | //Every thread runs 101 times CRUD operation.
164 | int runTimes = times;
165 | dispatch_async(queue, ^{
166 | CoreDataEnvir *db = [CoreDataEnvir instance];
167 |
168 | unsigned int c = counter;
169 | NSString *queueLabel = [NSString stringWithCString:dispatch_queue_get_label(queue) encoding:NSUTF8StringEncoding];
170 |
171 | for (int i = 0; i < runTimes; i++) {
172 | Team *team = (Team *)[Team lastItemInContext:db usingPredicate:[NSPredicate predicateWithFormat:@"name==%@", queueLabel]];
173 |
174 | //Delete item.
175 | if (team) {
176 | [team removeFrom:db];
177 | team.number = @(0 + c * 10000);
178 | NSLog(@"testing queue :%@; team.number :%@", queueLabel, team.number);
179 | }
180 | else {
181 | //Inset item.
182 | [Team insertItemInContext:db fillData:^(Team *item) {
183 | item.name = queueLabel;
184 | item.number = @(0 + c * 10000);
185 | }];
186 | }
187 | [db saveDataBase];
188 | }
189 | dispatch_semaphore_wait(self->__runs_sema, ~0ull);
190 | runs_forever--;
191 | dispatch_semaphore_signal(self->__runs_sema);
192 | NSLog(@"runs_forever :%d", runs_forever);
193 | });
194 | }
195 |
196 | int counter = 0;
197 | - (void)onClick_test:(id)sender
198 | {
199 |
200 | #if testing_case == TESTING_A
201 |
202 | if (runs_forever <= 0) {
203 | dispatch_semaphore_wait(__runs_sema, ~0ull);
204 | runs_forever = THREAD_NUMBER;
205 | dispatch_semaphore_signal(__runs_sema);
206 | [self updateDatabaseOnMainThread];
207 | }
208 |
209 | for (int i = 0; i < THREAD_NUMBER; i++) {
210 | dispatch_queue_t q1 = NULL;
211 | //Start 20 thread for testing, every thread runs CRUD operation 101 times on Name "com.cyblion".
212 | q1 = dispatch_queue_create([[NSString stringWithFormat:@"com.cyblion.%d", i] cStringUsingEncoding:NSUTF8StringEncoding], NULL);
213 |
214 | if (q1) {
215 | [self runTestA:q1 withTimes:LOOP_NUMBER_PER_THREAD];
216 | }
217 | //dispatch_release(q1);
218 | }
219 |
220 | #elif testing_case == TESTING_B
221 |
222 | for (int i = 0; i < THREAD_NUMBER; i++) {
223 | dispatch_queue_t q1 = NULL;
224 |
225 | //Start 'THREAD_NUMBER' thread for testing, every thread runs CRUD operation 'LOOP_NUMBER_PER_THREAD' times seperately.
226 | q1 = dispatch_queue_create([[NSString stringWithFormat:@"com.cyblion.%d", ++counter] cStringUsingEncoding:NSUTF8StringEncoding], NULL);
227 | if (q1) {
228 | [self runTestB:q1 withTimes:LOOP_NUMBER_PER_THREAD];
229 | dispatch_release(q1);
230 | }
231 | }
232 |
233 | #elif testing_case == TESTING_C
234 |
235 |
236 | dispatch_queue_t q = dispatch_queue_create([[NSString stringWithFormat:@"com.cyblion.testing_c"] cStringUsingEncoding:NSUTF8StringEncoding], NULL);
237 |
238 | dispatch_async(q, ^{
239 | int i = 0;
240 |
241 | for (i = 1; i <= 1024; i++) {
242 | NSLog(@"\n\n\n===========================");
243 | NSLog(@"Instance number [%d]", i);
244 | #if 1
245 | CoreDataEnvir *cde = [CoreDataEnvir createInstanceShareingPersistence:NO];
246 | if (!cde) {
247 | break;
248 | }
249 | #else
250 | //Pure manual code.
251 | NSManagedObjectContext * context = [[[NSManagedObjectContext alloc] init] autorelease];
252 | [context setRetainsRegisteredObjects:NO];
253 | [context setPropagatesDeletesAtEndOfEvent:NO];
254 | [context setMergePolicy:NSOverwriteMergePolicy];
255 |
256 | NSString *momdPath = [[NSBundle mainBundle] pathForResource:@"SampleModel" ofType:@"momd"];
257 | NSURL *momdURL = [NSURL fileURLWithPath:momdPath];
258 | NSManagedObjectModel *_m = [[[NSManagedObjectModel alloc] initWithContentsOfURL:momdURL] autorelease];
259 | if (!_m) {
260 | NSLog(@"Reached number %d", i);
261 | break;
262 | }
263 |
264 | NSPersistentStoreCoordinator *psc = [[[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:_m] autorelease];
265 |
266 | NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
267 | [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
268 | [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,
269 | nil];
270 |
271 | NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
272 |
273 | [psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/db.sqlite", path]] options:options error:nil];
274 | [context setPersistentStoreCoordinator:psc];
275 | #endif
276 | if (i + 1 >= 1025) {
277 | break;
278 | }
279 | }
280 |
281 | dispatch_async(dispatch_get_main_queue(), ^{
282 | NSString *message = [NSString stringWithFormat:@"Reaching number %d", i];
283 | UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:@"" message:message delegate:nil cancelButtonTitle:@"Close" otherButtonTitles: nil] autorelease];
284 | [alert show];
285 | });
286 |
287 | });
288 | dispatch_release(q);
289 |
290 |
291 | #elif TESTING_D
292 | NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
293 | NSString *filePath = [NSString stringWithFormat:@"%@/db.sqlite", path];
294 |
295 | NSInputStream *ises[1024];
296 |
297 | for (int i = 1; i <= 1024; i++) {
298 | NSLog(@"open :%d", i);
299 | NSInputStream *is = [[NSInputStream inputStreamWithFileAtPath:filePath] retain];
300 | [is open];
301 | ises[i - 1] = is;
302 | }
303 |
304 | uint8_t buffer[1024];
305 | for (int i = 1; i <= 1024; i++) {
306 | NSLog(@"read :%d", i);
307 | [ises[i - 1] read:buffer maxLength:1024];
308 | }
309 |
310 | #endif
311 |
312 |
313 | }
314 |
315 | - (void)onClick_clearAll:(id)sender
316 | {
317 | dispatch_async(dispatch_get_global_queue(0, 0), ^{
318 | CoreDataEnvir *db = [CoreDataEnvir instance];
319 |
320 | NSArray *teams = [Team itemsInContext:db];
321 | [db deleteDataItems:teams];
322 |
323 | NSArray *members = [Member itemsInContext:db];
324 | [db deleteDataItems:members];
325 |
326 | [db saveDataBase];
327 | });
328 | }
329 |
330 | - (void)onClick_look:(id)sender
331 | {
332 | NSArray *teams = [Team items];
333 | NSArray *members = [Member items];
334 |
335 | Team *t = [Team lastItem];
336 |
337 | if (!self.teamOnMainThread) {
338 | self.teamOnMainThread = [Team lastItem];
339 | }
340 |
341 | NSString *message = [NSString stringWithFormat:@"teams :%lu\nmembers :%lu\nTeam name:%@ number:%@\n t number:%@", [teams count], [members count], self.teamOnMainThread.name, self.teamOnMainThread.number, t.number];
342 | NSLog(@"team background :%@", self.teamOnBackground);
343 | // t.number = @(0);
344 | // [t save];
345 |
346 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:message delegate:Nil cancelButtonTitle:@"Close" otherButtonTitles: nil];
347 | [alert show];
348 | }
349 |
350 | - (BOOL)shouldRescureCoreData
351 | {
352 | return YES;
353 | }
354 |
355 | - (void)didStartRescureCoreData:(CoreDataEnvir *)cde
356 | {
357 |
358 | }
359 |
360 | - (void)didFinishedRescuringCoreData:(CoreDataEnvir *)cde
361 | {
362 |
363 | }
364 |
365 | - (void)rescureFailed:(CoreDataEnvir *)cde
366 | {
367 |
368 | }
369 |
370 |
371 | @end
372 |
--------------------------------------------------------------------------------
/CoreDataEnvirSample/CoreDataEnvirSample-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | //
2 | // Use this file to import your target's public headers that you would like to expose to Swift.
3 | //
4 |
5 | #import "Team.h"
6 | #import "Member.h"
7 | #if __has_include()
8 | #import
9 | #endif
10 |
--------------------------------------------------------------------------------
/CoreDataEnvirSample/RelationshipViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // RelationshipViewController.h
3 | // CoreDataEnvirSample
4 | //
5 | // Created by Deheng.Xu on 13-9-26.
6 | // Copyright (c) 2013年 Nicholas.Xu. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface RelationshipViewController : UIViewController
12 |
13 | - (IBAction)onClick_init:(id)sender;
14 | - (IBAction)onClick_load:(id)sender;
15 | - (IBAction)onClick_clearAll:(id)sender;
16 | - (IBAction)onClick_clearTeams:(id)sender;
17 | - (IBAction)onClick_clearMembers:(id)sender;
18 |
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/CoreDataEnvirSample/RelationshipViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // RelationshipViewController.m
3 | // CoreDataEnvirSample
4 | //
5 | // Created by Deheng.Xu on 13-9-26.
6 | // Copyright (c) 2013年 Nicholas.Xu. All rights reserved.
7 | //
8 |
9 | #import "RelationshipViewController.h"
10 |
11 | //#import "CoreDataEnvirHeader.h"
12 | #import
13 | @import CoreDataEnvir;
14 | #import "Team.h"
15 | #import "Member.h"
16 |
17 | #define BUTTONS_NUMBER 5
18 |
19 | @interface RelationshipViewController ()
20 |
21 | @end
22 |
23 | @implementation RelationshipViewController
24 |
25 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
26 | {
27 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
28 | if (self) {
29 | // Custom initialization
30 |
31 | }
32 | return self;
33 | }
34 |
35 | - (void)viewDidLoad
36 | {
37 | [super viewDidLoad];
38 | // Do any additional setup after loading the view.
39 | self.view.backgroundColor = [UIColor lightGrayColor];
40 |
41 | NSString * actions[BUTTONS_NUMBER] = {@"onClick_init:", @"onClick_load:", @"onClick_clearAll:", @"onClick_clearTeams:", @"onClick_clearMembers:"};
42 | NSString * titles[BUTTONS_NUMBER] = {@"Init", @"Watch", @"Clear All", @"Clear Teams", @"Cleaer Members"};
43 |
44 | CGSize buttonSize = CGSizeMake(180, 60);
45 |
46 | for (int i = 0; i < BUTTONS_NUMBER; i++) {
47 |
48 | UIButton *btn = [[UIButton alloc] initWithFrame:CGRectZero];
49 | btn.frame = CGRectMake(20, 20 + self.navigationController.navigationBar.frame.size.height + i * buttonSize.height, buttonSize.width, buttonSize.height);
50 | [btn addTarget:self action:NSSelectorFromString(actions[i]) forControlEvents:UIControlEventTouchUpInside];
51 | [btn setTitle:titles[i] forState:UIControlStateNormal];
52 | [self.view addSubview:btn];
53 |
54 | }
55 |
56 | }
57 |
58 | - (void)didReceiveMemoryWarning
59 | {
60 | [super didReceiveMemoryWarning];
61 | // Dispose of any resources that can be recreated.
62 | }
63 |
64 | - (void)onClick_init:(id)sender
65 | {
66 | Team *team1 = [Team insertItem];
67 | for (int i = 0; i < 20; i ++) {
68 | Member *mem = [Member insertItemWithFillingBlock:^(Member *item) {
69 | item.name = [NSString stringWithFormat:@"T1_M%d", i];
70 | item.belongedTeam = team1;
71 | }];
72 | [team1 addMembersObject:mem];
73 | [mem save];
74 | }
75 |
76 | Team *team2 = [Team insertItem];
77 | for (int i = 0; i < 20; i ++) {
78 | Member *mem = [Member insertItemWithFillingBlock:^(Member *item) {
79 | item.name = [NSString stringWithFormat:@"T2_M%d", i];
80 | item.belongedTeam = team2;
81 | }];
82 | [team2 addMembersObject:mem];
83 | [mem save];
84 | }
85 | }
86 |
87 | - (void)onClick_load:(id)sender
88 | {
89 | CoreDataEnvir *db = [CoreDataEnvir instance];
90 | NSArray *teams = [Team itemsInContext:db];
91 | NSArray *members = [Member itemsInContext:db];
92 |
93 | int members_c = 0;
94 | for (Team *t in teams) {
95 | members_c += [t.members count];
96 | }
97 | NSString *message = [NSString stringWithFormat:@"teams %lu\nmembers of teams :%d\ntotal members :%lu.", [teams count], members_c, [members count]];
98 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:message delegate:Nil cancelButtonTitle:@"Close" otherButtonTitles: nil];
99 | [alert show];
100 |
101 | }
102 |
103 | - (void)onClick_clearAll:(id)sender
104 | {
105 | dispatch_async(dispatch_get_global_queue(0, 0), ^{
106 | CoreDataEnvir *db = [CoreDataEnvir instance];
107 |
108 | NSArray *members = [Member itemsInContext:db];
109 | [members makeObjectsPerformSelector:@selector(removeFrom:) withObject:db];
110 |
111 | NSArray *teams = [Team itemsInContext:db];
112 | [teams makeObjectsPerformSelector:@selector(removeFrom:) withObject:db];
113 |
114 |
115 | [db saveDataBase];
116 | });
117 |
118 | }
119 |
120 | - (void)onClick_clearTeams:(id)sender
121 | {
122 | dispatch_async(dispatch_get_global_queue(0, 0), ^{
123 | CoreDataEnvir *db = [CoreDataEnvir instance];
124 |
125 | NSArray *teams = [Team itemsInContext:db];
126 | [teams makeObjectsPerformSelector:@selector(removeFrom:) withObject:db];
127 | for (Team *t in teams) {
128 | t.members = nil;
129 | [t removeFrom:db];
130 | }
131 |
132 | [db saveDataBase];
133 | });
134 |
135 | }
136 |
137 | - (void)onClick_clearMembers:(id)sender
138 | {
139 | dispatch_async(dispatch_get_global_queue(0, 0), ^{
140 | CoreDataEnvir *db = [CoreDataEnvir instance];
141 |
142 | NSArray *members = [Member itemsInContext:db];
143 | for (Member *m in members) {
144 | m.belongedTeam = nil;
145 | [m removeFrom:db];
146 | }
147 |
148 | [db saveDataBase];
149 | });
150 |
151 | }
152 |
153 | @end
154 |
--------------------------------------------------------------------------------
/CoreDataEnvirSample/Supporting Files/CoreDataEnvirSample-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | ${PRODUCT_NAME}
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1.0
25 | LSRequiresIPhoneOS
26 |
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/CoreDataEnvirSample/Supporting Files/CoreDataEnvirSample-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header for all source files of the 'CoreDataEnvirSample' target in the 'CoreDataEnvirSample' project
3 | //
4 |
5 | #import
6 |
7 | #ifndef __IPHONE_4_0
8 | #warning "This project uses features only available in iOS SDK 4.0 and later."
9 | #endif
10 |
11 | #ifdef __OBJC__
12 | #import
13 | #import
14 | #import
15 | #endif
16 |
--------------------------------------------------------------------------------
/CoreDataEnvirSample/Supporting Files/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dehengxu/CoreDataEnvir/ee1cfa305b068f12c33d92ae0636cdea44ced7cb/CoreDataEnvirSample/Supporting Files/Default-568h@2x.png
--------------------------------------------------------------------------------
/CoreDataEnvirSample/Supporting Files/Default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dehengxu/CoreDataEnvir/ee1cfa305b068f12c33d92ae0636cdea44ced7cb/CoreDataEnvirSample/Supporting Files/Default.png
--------------------------------------------------------------------------------
/CoreDataEnvirSample/Supporting Files/Default@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dehengxu/CoreDataEnvir/ee1cfa305b068f12c33d92ae0636cdea44ced7cb/CoreDataEnvirSample/Supporting Files/Default@2x.png
--------------------------------------------------------------------------------
/CoreDataEnvirSample/Supporting Files/Member.h:
--------------------------------------------------------------------------------
1 | //
2 | // Member.h
3 | // CoreDataEnvirSample
4 | //
5 | // Created by Deheng.Xu on 13-9-26.
6 | // Copyright (c) 2013年 Nicholas.Xu. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @class Team;
13 |
14 | @interface Member : NSManagedObject
15 |
16 | @property (nonatomic, retain) NSNumber * age;
17 | @property (nonatomic, retain) NSDate * birthday;
18 | @property (nonatomic, retain) NSString * name;
19 | @property (nonatomic, retain) NSString * phonenum;
20 | @property (nonatomic, retain) Team *belongedTeam;
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/CoreDataEnvirSample/Supporting Files/Member.m:
--------------------------------------------------------------------------------
1 | //
2 | // Member.m
3 | // CoreDataEnvirSample
4 | //
5 | // Created by Deheng.Xu on 13-9-26.
6 | // Copyright (c) 2013年 Nicholas.Xu. All rights reserved.
7 | //
8 |
9 | #import "Member.h"
10 | #import "Team.h"
11 |
12 |
13 | @implementation Member
14 |
15 | @dynamic age;
16 | @dynamic birthday;
17 | @dynamic name;
18 | @dynamic phonenum;
19 | @dynamic belongedTeam;
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/CoreDataEnvirSample/Supporting Files/SampleModel.xcdatamodeld/SampleModel.xcdatamodel/contents:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/CoreDataEnvirSample/Supporting Files/Team.h:
--------------------------------------------------------------------------------
1 | //
2 | // Team.h
3 | // CoreDataEnvirSample
4 | //
5 | // Created by Deheng.Xu on 13-9-26.
6 | // Copyright (c) 2013年 Nicholas.Xu. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @class Member;
13 |
14 | @interface Team : NSManagedObject
15 |
16 | @property (nonatomic, retain) NSString * name;
17 | @property (nonatomic, retain) NSNumber * number;
18 | @property (nonatomic, retain) NSSet *members;
19 | @end
20 |
21 | @interface Team (CoreDataGeneratedAccessors)
22 |
23 | - (void)addMembersObject:(Member *)value;
24 | - (void)removeMembersObject:(Member *)value;
25 | - (void)addMembers:(NSSet *)values;
26 | - (void)removeMembers:(NSSet *)values;
27 | @end
28 |
--------------------------------------------------------------------------------
/CoreDataEnvirSample/Supporting Files/Team.m:
--------------------------------------------------------------------------------
1 | //
2 | // Team.m
3 | // CoreDataEnvirSample
4 | //
5 | // Created by Deheng.Xu on 13-9-26.
6 | // Copyright (c) 2013年 Nicholas.Xu. All rights reserved.
7 | //
8 |
9 | #import "Team.h"
10 | #import "Member.h"
11 |
12 |
13 | @implementation Team
14 |
15 | @dynamic name;
16 | @dynamic number;
17 | @dynamic members;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/CoreDataEnvirSample/Supporting Files/demo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Concurrency
6 | Relationship
7 | Swift
8 |
9 |
10 |
--------------------------------------------------------------------------------
/CoreDataEnvirSample/Supporting Files/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/CoreDataEnvirSample/Supporting Files/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // CoreDataEnvirSample
4 | //
5 | // Created by Deheng.Xu on 13-4-7.
6 | // Copyright (c) 2013年 Nicholas.Xu. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "AppDelegate.h"
12 |
13 | int main(int argc, char *argv[])
14 | {
15 | @autoreleasepool {
16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/CoreDataEnvirSample/SwiftViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SwiftViewController.swift
3 | // CoreDataEnvirSample
4 | //
5 | // Created by NicholasXu on 2020/9/14.
6 | // Copyright © 2020 Nicholas.Xu. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import CoreDataEnvir
11 |
12 | @objc(SwiftViewController)
13 | class SwiftViewController: UIViewController {
14 |
15 | @objc override func viewDidLoad() {
16 | super.viewDidLoad()
17 |
18 | CoreDataEnvir.mainInstance()
19 | print("Team.totalCount:", Team.totalCount())
20 | print("Member.totalCount:", Member.totalCount())
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/CoreDataEnvirSample/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // CoreDataEnvirSample
4 | //
5 | // Created by Deheng.Xu on 13-4-7.
6 | // Copyright (c) 2013年 Nicholas.Xu. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "CoreDataEnvir.h"
11 |
12 | @interface ViewController : UIViewController
13 | <
14 | UITableViewDelegate, UITableViewDataSource
15 | >
16 | {
17 | }
18 | @property (nonatomic, readonly, retain) NSArray *demonNames;
19 | @property (nonatomic, retain) UITableView *tableView;
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/CoreDataEnvirSample/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // CoreDataEnvirSample
4 | //
5 | // Created by Deheng.Xu on 13-4-7.
6 | // Copyright (c) 2013年 Nicholas.Xu. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | //#import "CoreDataEnvir.h"
11 | //#import "Team.h"
12 |
13 | #define THREAD_NUMBER 20
14 | #define LOOP_NUMBER_PER_THREAD 101
15 | #define TESTING_A 1
16 | #define TESTING_B 2
17 | #define testing_case TESTING_A
18 |
19 | @interface ViewController ()
20 |
21 | @end
22 |
23 | @implementation ViewController
24 |
25 | @synthesize demonNames = _demonNames;
26 |
27 | - (void)viewDidLoad
28 | {
29 | [super viewDidLoad];
30 | // Do any additional setup after loading the view, typically from a nib.
31 | self.tableView.delegate = self;
32 | self.tableView.dataSource = self;
33 | self.tableView.frame = self.view.bounds;
34 | self.tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
35 | [self.view addSubview:self.tableView];
36 | }
37 |
38 | - (void)viewWillAppear:(BOOL)animated
39 | {
40 | [self.tableView reloadData];
41 | }
42 |
43 | - (void)viewWillDisappear:(BOOL)animated
44 | {
45 | }
46 |
47 | - (void)didReceiveMemoryWarning
48 | {
49 | [super didReceiveMemoryWarning];
50 | // Dispose of any resources that can be recreated.
51 | }
52 |
53 | #pragma mark - lazy loading
54 |
55 | - (NSArray *)demonNames
56 | {
57 | if (!_demonNames) {
58 | _demonNames = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"demo" ofType:@"plist"]];
59 | }
60 | return _demonNames;
61 | }
62 |
63 | - (UITableView *)tableView
64 | {
65 | if (!_tableView) {
66 | _tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
67 | }
68 | return _tableView;
69 | }
70 |
71 | #pragma mark - table view delegate & data source
72 |
73 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
74 | {
75 | return 1;
76 | }
77 |
78 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
79 | {
80 | return [self.demonNames count];
81 | }
82 |
83 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
84 | {
85 | NSString *identifier = @"_table_view_cell_identifier";
86 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
87 |
88 | if (cell == nil) {
89 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
90 | }
91 |
92 | if (cell) {
93 | //Todo:Config cell object.
94 |
95 | cell.textLabel.text = [self.demonNames objectAtIndex:indexPath.row];
96 | }
97 |
98 | return cell;
99 | }
100 |
101 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
102 | {
103 | NSString* name = [NSString stringWithFormat:@"%@ViewController", [self.demonNames objectAtIndex:indexPath.row]];
104 | Class theClass = NSClassFromString(name);
105 |
106 | <<<<<<< HEAD
107 | UIViewController *vc = [[[theClass alloc] init] autorelease];
108 | =======
109 | UIViewController *vc = [[theClass alloc] init];
110 | >>>>>>> feature/arc
111 | if (vc) {
112 | [self.navigationController pushViewController:vc animated:YES];
113 | }else {
114 | NSLog(@"class: %@ not found.", name);
115 | }
116 | [[self.tableView cellForRowAtIndexPath:indexPath] setSelected:NO animated:YES];
117 | }
118 |
119 |
120 | @end
121 |
--------------------------------------------------------------------------------
/CoreDataEnvirSample/zh-Hans.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dehengxu/CoreDataEnvir/ee1cfa305b068f12c33d92ae0636cdea44ced7cb/CoreDataEnvirSample/zh-Hans.lproj/InfoPlist.strings
--------------------------------------------------------------------------------
/CoreDataEnvirSampleTests/CoreDataEnvirTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // CoreDataEnvirTests.m
3 | // CoreDataEnvirSampleTests
4 | //
5 | // Created by NicholasXu on 2020/9/18.
6 | // Copyright © 2020 Nicholas.Xu. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface CoreDataEnvirTests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation CoreDataEnvirTests
16 |
17 | - (void)setUp {
18 | // Put setup code here. This method is called before the invocation of each test method in the class.
19 | }
20 |
21 | - (void)tearDown {
22 | // Put teardown code here. This method is called after the invocation of each test method in the class.
23 | }
24 |
25 | - (void)testExample {
26 | // This is an example of a functional test case.
27 | // Use XCTAssert and related functions to verify your tests produce the correct results.
28 | }
29 |
30 | - (void)testPerformanceExample {
31 | // This is an example of a performance test case.
32 | [self measureBlock:^{
33 | // Put the code you want to measure the time of here.
34 | }];
35 | }
36 |
37 | @end
38 |
--------------------------------------------------------------------------------
/CoreDataEnvirSampleTests/Supporting Files/CoreDataEnvirSampleTests-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundlePackageType
14 | BNDL
15 | CFBundleShortVersionString
16 | 1.0
17 | CFBundleSignature
18 | ????
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/CoreDataEnvirSampleTests/Supporting Files/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/CoreDataEnvirSampleTests/Supporting Files/zh-Hans.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/CoreDataEnvirTests/CoreDataEnvirTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // CoreDataEnvirTests.m
3 | // CoreDataEnvirTests
4 | //
5 | // Created by NicholasXu on 2020/9/21.
6 | // Copyright © 2020 Nicholas.Xu. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface CoreDataEnvirTests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation CoreDataEnvirTests
16 |
17 | - (void)setUp {
18 | // Put setup code here. This method is called before the invocation of each test method in the class.
19 | }
20 |
21 | - (void)tearDown {
22 | // Put teardown code here. This method is called after the invocation of each test method in the class.
23 | }
24 |
25 | - (void)testExample {
26 | // This is an example of a functional test case.
27 | // Use XCTAssert and related functions to verify your tests produce the correct results.
28 | }
29 |
30 | - (void)testPerformanceExample {
31 | // This is an example of a performance test case.
32 | [self measureBlock:^{
33 | // Put the code you want to measure the time of here.
34 | }];
35 | }
36 |
37 | @end
38 |
--------------------------------------------------------------------------------
/CoreDataEnvirTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2011/05/25 Deheng.Xu
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Member+CoreDataClass.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Member+CoreDataClass.swift
3 | //
4 | //
5 | // Created by NicholasXu on 2020/9/14.
6 | //
7 | //
8 |
9 | import Foundation
10 | import CoreData
11 | import CoreDaaEnvir
12 |
13 | @objc(Member)
14 | public class Member: NSManagedObject {
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/Member+CoreDataProperties.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Member+CoreDataProperties.swift
3 | //
4 | //
5 | // Created by NicholasXu on 2020/9/14.
6 | //
7 | //
8 |
9 | import Foundation
10 | import CoreData
11 |
12 |
13 | extension Member {
14 |
15 | @nonobjc public class func fetchRequest() -> NSFetchRequest {
16 | return NSFetchRequest(entityName: "Member")
17 | }
18 |
19 | @NSManaged public var age: NSNumber?
20 | @NSManaged public var birthday: Date?
21 | @NSManaged public var name: String?
22 | @NSManaged public var phonenum: String?
23 | @NSManaged public var belongedTeam: Team?
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/ObjcUML/Scripts/d3js-LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2013, Michael Bostock
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 |
7 | * Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | * Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation
12 | and/or other materials provided with the distribution.
13 |
14 | * The name Michael Bostock may not be used to endorse or promote products
15 | derived from this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | DISCLAIMED. IN NO EVENT SHALL MICHAEL BOSTOCK BE LIABLE FOR ANY DIRECT,
21 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
24 | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 |
--------------------------------------------------------------------------------
/ObjcUML/Scripts/parse.js:
--------------------------------------------------------------------------------
1 | // ===================================================
2 | // =============== PARSING ===========================
3 | // ===================================================
4 | // Input
5 | // { links : [ {source: sourceName, dest : destName} * ] }
6 | // Output:
7 | !function () {
8 | var objcdv = {
9 | version: "0.0.1"
10 | };
11 | objcdv.parse_dependencies_graph = function (dependencies, regexp_color_matchers) {
12 |
13 | var nodes = [];
14 | var links = [];
15 |
16 | var nodesSet = {};
17 | var prefixes = {};
18 |
19 | var node_index = 0;
20 |
21 | // Parse all dependencies
22 | // In format
23 |
24 | var input_links = dependencies.links;
25 |
26 | var updatePrefixesDistribution = function(name) {
27 | var prefix = name.substring(0, 2);
28 | if (!(prefix in prefixes)) {
29 | prefixes[prefix] = 1;
30 | } else {
31 | prefixes[prefix]++;
32 | }
33 | }
34 |
35 | for (var i = 0; i < input_links.length; i++) {
36 | var link = input_links[i];
37 |
38 | var source_node = nodesSet[link.source];
39 | if (source_node == null) {
40 | nodesSet[link.source] = source_node = { idx :node_index++, name: link.source, source: 1, dest: 0 }
41 | }
42 | source_node.source++;
43 |
44 | var dest_node = nodesSet[link.dest];
45 | if (dest_node == null) {
46 | nodesSet[link.dest] = dest_node = { idx :node_index++, name: link.dest, source: 0, dest: 1 }
47 | }
48 | dest_node.dest++;
49 |
50 |
51 | // Grouping by prefixes
52 | updatePrefixesDistribution(link.source);
53 | updatePrefixesDistribution(link.dest);
54 |
55 | // Remapping links objects
56 | links.push({
57 |
58 | // d3 js properties
59 | source: source_node.idx,
60 | target: dest_node.idx,
61 |
62 | // Additional link information
63 | sourceNode: source_node,
64 | targetNode: dest_node
65 | });
66 |
67 | console.log("Pushing link : source=" + source_node.idx + ", target=" + dest_node.idx);
68 | }
69 |
70 |
71 | // Sorting prefixes, based on theirs frequency
72 | var prefixes_arr = [];
73 | for (var key in prefixes) {
74 | prefixes_arr.push({key: key, value: prefixes[key] });
75 | }
76 | var sorted_prefixes = prefixes_arr.slice(0).sort(function (a, b) {
77 | return b.value - a.value;
78 | });
79 |
80 | // If we dont' have regexp_color_matchers, we'll set them up, based on prefixes
81 | var group_regexp_identifiers = regexp_color_matchers;
82 | if (group_regexp_identifiers == null) {
83 | group_regexp_identifiers = [];
84 | for (var i = 0; i < sorted_prefixes.length; i++) {
85 | group_regexp_identifiers.push("^" + sorted_prefixes[i].key+".*");
86 | }
87 | }
88 |
89 | // Setting up nodes groups, based on the group_regexp_identifiers
90 | var idx = 0;
91 | for (var p in nodesSet) {
92 |
93 | node = nodesSet[p];
94 | node.group = 0;
95 | node.weight = node.source; // Calculating node weignt, based on the amount of item it depends on
96 |
97 | for (var regexp_index = 0; regexp_index < group_regexp_identifiers.length; regexp_index++) {
98 | var re = new RegExp(group_regexp_identifiers[regexp_index], "");
99 | if (p.match(re)) {
100 | node.group = regexp_index + 1;
101 | break;
102 | }
103 | }
104 |
105 | nodes.push(node);
106 | console.log(" Pushing node : IDX=" + idx + ", name=" + p + ", groupId=" + node.group + ", source=" + node.source + ", dest=" + node.dest + ", weight=" + node.weight);
107 | idx++;
108 | }
109 |
110 | return { nodes : nodes, links: links };
111 | }
112 |
113 | if (typeof define === "function" && define.amd) {
114 | define(objcdv);
115 | } else if (typeof module === "object" && module.exports) {
116 | module.exports = objcdv;
117 | } else {
118 | this.objcdv = objcdv;
119 | }
120 | }();
121 |
122 |
--------------------------------------------------------------------------------
/ObjcUML/dependency.css:
--------------------------------------------------------------------------------
1 |
2 |
3 | .node.filtered {
4 | fill-opacity:0.3;
5 | stroke-opacity:0.3;
6 | }
7 |
8 | text.filtered {
9 | fill-opacity:0;
10 | stroke-opacity:0;
11 | }
12 |
13 | .link.filtered {
14 | stroke: #ddd;
15 | fill-opacity:0.1;
16 | stroke-opacity:0.1;
17 | }
18 |
19 | .node {
20 | stroke: #000;
21 | stroke-width: 0.5px;
22 | }
23 |
24 | .link {
25 | stroke: #999;
26 | stroke-opacity: .6;
27 | fill: none;
28 | stroke-width: 1.5px;
29 | pointer-events: none;
30 | }
31 |
32 | .marker#default {
33 | stroke: #999;
34 | fill:#999;
35 | pointer-events: none;
36 | }
37 |
38 | .marker#dependency {
39 | stroke: #900;
40 | fill:#900;
41 | pointer-events: none;
42 | }
43 |
44 | .marker#dependants {
45 | stroke: #090;
46 | fill:#090;
47 | pointer-events: none;
48 | }
49 |
50 |
51 | text {
52 | stroke: #000;
53 | stroke-width: 0.5px;
54 | text-anchor:middle;
55 | font: 10px sans-serif;
56 | font-weight: normal;
57 | font-style: normal;
58 | pointer-events: none;
59 | }
60 |
61 | form {
62 | position: absolute;
63 | right: 10px;
64 | top: 10px;
65 | }
--------------------------------------------------------------------------------
/ObjcUML/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
22 |
23 |
24 |
25 |
26 |
27 |
416 |
417 |
448 |
449 |
450 |
--------------------------------------------------------------------------------
/ObjcUML/origin.js:
--------------------------------------------------------------------------------
1 | var dependencies = {
2 | links:
3 | [
4 | { "source" : "AppDelegate", "dest" : "CoreDataEnvir" },
5 | { "source" : "AppDelegate", "dest" : "ViewController" },
6 | { "source" : "ConcurrencyViewController", "dest" : "CoreDataEnvir" },
7 | { "source" : "ConcurrencyViewController", "dest" : "Member" },
8 | { "source" : "ConcurrencyViewController", "dest" : "Team" },
9 | { "source" : "CoreDataEnvir_Background", "dest" : "CoreDataEnvir" },
10 | { "source" : "main", "dest" : "AppDelegate" },
11 | { "source" : "RelationshipViewController", "dest" : "CoreDataEnvir" },
12 | { "source" : "RelationshipViewController", "dest" : "Member" },
13 | { "source" : "RelationshipViewController", "dest" : "Team" },
14 | { "source" : "AppDelegate", "dest" : "ViewController" },
15 | { "source" : "ConcurrencyViewController", "dest" : "Team" },
16 | { "source" : "ConcurrencyViewController", "dest" : "CoreDataEnvir" },
17 | { "source" : "CoreDataEnvir_Background", "dest" : "CoreDataEnvir" },
18 | { "source" : "Member", "dest" : "Team" },
19 | { "source" : "RelationshipViewController", "dest" : "Team" },
20 | { "source" : "RelationshipViewController", "dest" : "Member" },
21 | { "source" : "RelationshipViewController", "dest" : "CoreDataEnvir" },
22 | ]
23 | }
24 | ;
25 |
--------------------------------------------------------------------------------
/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment the next line to define a global platform for your project
2 | platform :ios, '9.0'
3 |
4 | #target 'CoreDataEnvirFramework' do
5 | # # Comment the next line if you don't want to use dynamic frameworks
6 | # use_frameworks!
7 | #
8 | # # Pods for CoreDataEnvir
9 | #
10 | # target 'CoreDataEnvirFrameworkTests' do
11 | # # Pods for testing
12 | # end
13 | #
14 | #end
15 |
16 | target 'CoreDataEnvirSample' do
17 | # Comment the next line if you don't want to use dynamic frameworks
18 | use_frameworks!
19 |
20 | # Pods for CoreDataEnvirSample
21 | pod 'CoreDataEnvir', :path => './'
22 | end
23 |
24 | target 'CoreDataEnvirSampleTests' do
25 | # Comment the next line if you don't want to use dynamic frameworks
26 | use_frameworks!
27 |
28 | # Pods for CoreDataEnvirSampleTests
29 |
30 | end
31 |
--------------------------------------------------------------------------------
/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - CoreDataEnvir (0.13.0-beta.1)
3 |
4 | DEPENDENCIES:
5 | - CoreDataEnvir (from `./`)
6 |
7 | EXTERNAL SOURCES:
8 | CoreDataEnvir:
9 | :path: "./"
10 |
11 | SPEC CHECKSUMS:
12 | CoreDataEnvir: b1e194fb4f9c0c1379e41aa279914e846532e818
13 |
14 | PODFILE CHECKSUM: ca1c3555763228eec892767a892b60d23cd1cb85
15 |
16 | COCOAPODS: 1.9.3
17 |
--------------------------------------------------------------------------------
/Pods/Local Podspecs/CoreDataEnvir.podspec.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "CoreDataEnvir",
3 | "version": "0.13.0-beta.1",
4 | "summary": "CoreDataEnvir is a CoreData wrapper which use CoreData in convient way and supply thread safe in concurrenct programming.",
5 | "description": "CoreDataEnvir is a CoreData wrapper which use CoreData in convient way and supply thread safe in concurrenct programming. You can use it concurrenctly,run seperate CoreDataEnvir instance on one thread.",
6 | "homepage": "https://dehengxu.github.io/CoreDataEnvir",
7 | "module_name": "CoreDataEnvir",
8 | "license": "MIT",
9 | "authors": {
10 | "DehengXu": "dehengxu@outlook.com"
11 | },
12 | "social_media_url": "https://github.com/dehengxu",
13 | "platforms": {
14 | "ios": "10.0"
15 | },
16 | "source": {
17 | "git": "https://github.com/dehengxu/CoreDataEnvir.git",
18 | "tag": "0.13.0-beta.1"
19 | },
20 | "source_files": [
21 | "src/CoreDataEnvir/*.h",
22 | "src/CoreDataEnvir/**/*.{h,m}"
23 | ],
24 | "public_header_files": "src/CoreDataEnvir/**/*.h",
25 | "frameworks": "CoreData",
26 | "requires_arc": true,
27 | "info_plist": {
28 | "CFBundleIdentifier": "com.dehengxu.CoreDataEnvir"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Pods/Manifest.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - CoreDataEnvir (0.13.0-beta.1)
3 |
4 | DEPENDENCIES:
5 | - CoreDataEnvir (from `./`)
6 |
7 | EXTERNAL SOURCES:
8 | CoreDataEnvir:
9 | :path: "./"
10 |
11 | SPEC CHECKSUMS:
12 | CoreDataEnvir: b1e194fb4f9c0c1379e41aa279914e846532e818
13 |
14 | PODFILE CHECKSUM: ca1c3555763228eec892767a892b60d23cd1cb85
15 |
16 | COCOAPODS: 1.9.3
17 |
--------------------------------------------------------------------------------
/Pods/Pods.xcodeproj/xcuserdata/dehengxu.xcuserdatad/xcschemes/CoreDataEnvir.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
44 |
45 |
46 |
52 |
53 |
55 |
56 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/Pods/Pods.xcodeproj/xcuserdata/dehengxu.xcuserdatad/xcschemes/Pods-CoreDataEnvirSample.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
44 |
50 |
51 |
53 |
54 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/Pods/Pods.xcodeproj/xcuserdata/dehengxu.xcuserdatad/xcschemes/Pods-CoreDataEnvirSampleTests.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
44 |
50 |
51 |
53 |
54 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/Pods/Pods.xcodeproj/xcuserdata/dehengxu.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | CoreDataEnvir.xcscheme
8 |
9 | isShown
10 |
11 |
12 | Pods-CoreDataEnvirSample.xcscheme
13 |
14 | isShown
15 |
16 |
17 | Pods-CoreDataEnvirSampleTests.xcscheme
18 |
19 | isShown
20 |
21 |
22 |
23 | SuppressBuildableAutocreation
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/CoreDataEnvir/CoreDataEnvir-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | com.dehengxu.CoreDataEnvir
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ${PRODUCT_NAME}
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 0.13.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/CoreDataEnvir/CoreDataEnvir-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_CoreDataEnvir : NSObject
3 | @end
4 | @implementation PodsDummy_CoreDataEnvir
5 | @end
6 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/CoreDataEnvir/CoreDataEnvir-prefix.pch:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/CoreDataEnvir/CoreDataEnvir-umbrella.h:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 | #import "CoreDataEnvir.h"
14 | #import "CoreDataEnvirDescriptor.h"
15 | #import "CoreDataEnvirHeader.h"
16 | #import "CoreDataEnvirObserver.h"
17 | #import "CoreDataEnvir_Background.h"
18 | #import "CoreDataEnvir_Main.h"
19 | #import "CoreDataRescureDelegate.h"
20 | #import "NSManagedObject_Background.h"
21 | #import "NSManagedObject_Convenient.h"
22 | #import "NSManagedObject_MainThread.h"
23 | #import "CoreDataEnvir_Private.h"
24 |
25 | FOUNDATION_EXPORT double CoreDataEnvirVersionNumber;
26 | FOUNDATION_EXPORT const unsigned char CoreDataEnvirVersionString[];
27 |
28 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/CoreDataEnvir/CoreDataEnvir.debug.xcconfig:
--------------------------------------------------------------------------------
1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CoreDataEnvir
2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
3 | OTHER_LDFLAGS = $(inherited) -framework "CoreData"
4 | PODS_BUILD_DIR = ${BUILD_DIR}
5 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
6 | PODS_ROOT = ${SRCROOT}
7 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/..
8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
9 | SKIP_INSTALL = YES
10 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
11 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/CoreDataEnvir/CoreDataEnvir.modulemap:
--------------------------------------------------------------------------------
1 | framework module CoreDataEnvir {
2 | umbrella header "CoreDataEnvir-umbrella.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/CoreDataEnvir/CoreDataEnvir.release.xcconfig:
--------------------------------------------------------------------------------
1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CoreDataEnvir
2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
3 | OTHER_LDFLAGS = $(inherited) -framework "CoreData"
4 | PODS_BUILD_DIR = ${BUILD_DIR}
5 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
6 | PODS_ROOT = ${SRCROOT}
7 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/..
8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
9 | SKIP_INSTALL = YES
10 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
11 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-CoreDataEnvirSample/Pods-CoreDataEnvirSample-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | ${PRODUCT_BUNDLE_IDENTIFIER}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ${PRODUCT_NAME}
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-CoreDataEnvirSample/Pods-CoreDataEnvirSample-acknowledgements.markdown:
--------------------------------------------------------------------------------
1 | # Acknowledgements
2 | This application makes use of the following third party libraries:
3 |
4 | ## CoreDataEnvir
5 |
6 | The MIT License (MIT)
7 |
8 | Copyright (c) 2011/05/25 Deheng.Xu
9 |
10 | Permission is hereby granted, free of charge, to any person obtaining a copy
11 | of this software and associated documentation files (the "Software"), to deal
12 | in the Software without restriction, including without limitation the rights
13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 | copies of the Software, and to permit persons to whom the Software is
15 | furnished to do so, subject to the following conditions:
16 |
17 | The above copyright notice and this permission notice shall be included in
18 | all copies or substantial portions of the Software.
19 |
20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 | THE SOFTWARE.
27 |
28 | Generated by CocoaPods - https://cocoapods.org
29 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-CoreDataEnvirSample/Pods-CoreDataEnvirSample-acknowledgements.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreferenceSpecifiers
6 |
7 |
8 | FooterText
9 | This application makes use of the following third party libraries:
10 | Title
11 | Acknowledgements
12 | Type
13 | PSGroupSpecifier
14 |
15 |
16 | FooterText
17 | The MIT License (MIT)
18 |
19 | Copyright (c) 2011/05/25 Deheng.Xu
20 |
21 | Permission is hereby granted, free of charge, to any person obtaining a copy
22 | of this software and associated documentation files (the "Software"), to deal
23 | in the Software without restriction, including without limitation the rights
24 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
25 | copies of the Software, and to permit persons to whom the Software is
26 | furnished to do so, subject to the following conditions:
27 |
28 | The above copyright notice and this permission notice shall be included in
29 | all copies or substantial portions of the Software.
30 |
31 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
32 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
33 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
34 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
35 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
36 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
37 | THE SOFTWARE.
38 |
39 | License
40 | MIT
41 | Title
42 | CoreDataEnvir
43 | Type
44 | PSGroupSpecifier
45 |
46 |
47 | FooterText
48 | Generated by CocoaPods - https://cocoapods.org
49 | Title
50 |
51 | Type
52 | PSGroupSpecifier
53 |
54 |
55 | StringsTable
56 | Acknowledgements
57 | Title
58 | Acknowledgements
59 |
60 |
61 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-CoreDataEnvirSample/Pods-CoreDataEnvirSample-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_Pods_CoreDataEnvirSample : NSObject
3 | @end
4 | @implementation PodsDummy_Pods_CoreDataEnvirSample
5 | @end
6 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-CoreDataEnvirSample/Pods-CoreDataEnvirSample-frameworks-Debug-input-files.xcfilelist:
--------------------------------------------------------------------------------
1 | ${PODS_ROOT}/Target Support Files/Pods-CoreDataEnvirSample/Pods-CoreDataEnvirSample-frameworks.sh
2 | ${BUILT_PRODUCTS_DIR}/CoreDataEnvir/CoreDataEnvir.framework
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-CoreDataEnvirSample/Pods-CoreDataEnvirSample-frameworks-Debug-output-files.xcfilelist:
--------------------------------------------------------------------------------
1 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CoreDataEnvir.framework
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-CoreDataEnvirSample/Pods-CoreDataEnvirSample-frameworks-Release-input-files.xcfilelist:
--------------------------------------------------------------------------------
1 | ${PODS_ROOT}/Target Support Files/Pods-CoreDataEnvirSample/Pods-CoreDataEnvirSample-frameworks.sh
2 | ${BUILT_PRODUCTS_DIR}/CoreDataEnvir/CoreDataEnvir.framework
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-CoreDataEnvirSample/Pods-CoreDataEnvirSample-frameworks-Release-output-files.xcfilelist:
--------------------------------------------------------------------------------
1 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CoreDataEnvir.framework
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-CoreDataEnvirSample/Pods-CoreDataEnvirSample-frameworks.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -e
3 | set -u
4 | set -o pipefail
5 |
6 | function on_error {
7 | echo "$(realpath -mq "${0}"):$1: error: Unexpected failure"
8 | }
9 | trap 'on_error $LINENO' ERR
10 |
11 | if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then
12 | # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy
13 | # frameworks to, so exit 0 (signalling the script phase was successful).
14 | exit 0
15 | fi
16 |
17 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
18 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
19 |
20 | COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}"
21 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
22 |
23 | # Used as a return value for each invocation of `strip_invalid_archs` function.
24 | STRIP_BINARY_RETVAL=0
25 |
26 | # This protects against multiple targets copying the same framework dependency at the same time. The solution
27 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
28 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
29 |
30 | # Copies and strips a vendored framework
31 | install_framework()
32 | {
33 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
34 | local source="${BUILT_PRODUCTS_DIR}/$1"
35 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then
36 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")"
37 | elif [ -r "$1" ]; then
38 | local source="$1"
39 | fi
40 |
41 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
42 |
43 | if [ -L "${source}" ]; then
44 | echo "Symlinked..."
45 | source="$(readlink "${source}")"
46 | fi
47 |
48 | # Use filter instead of exclude so missing patterns don't throw errors.
49 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
50 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
51 |
52 | local basename
53 | basename="$(basename -s .framework "$1")"
54 | binary="${destination}/${basename}.framework/${basename}"
55 |
56 | if ! [ -r "$binary" ]; then
57 | binary="${destination}/${basename}"
58 | elif [ -L "${binary}" ]; then
59 | echo "Destination binary is symlinked..."
60 | dirname="$(dirname "${binary}")"
61 | binary="${dirname}/$(readlink "${binary}")"
62 | fi
63 |
64 | # Strip invalid architectures so "fat" simulator / device frameworks work on device
65 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then
66 | strip_invalid_archs "$binary"
67 | fi
68 |
69 | # Resign the code if required by the build settings to avoid unstable apps
70 | code_sign_if_enabled "${destination}/$(basename "$1")"
71 |
72 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7.
73 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then
74 | local swift_runtime_libs
75 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u)
76 | for lib in $swift_runtime_libs; do
77 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\""
78 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}"
79 | code_sign_if_enabled "${destination}/${lib}"
80 | done
81 | fi
82 | }
83 |
84 | # Copies and strips a vendored dSYM
85 | install_dsym() {
86 | local source="$1"
87 | warn_missing_arch=${2:-true}
88 | if [ -r "$source" ]; then
89 | # Copy the dSYM into the targets temp dir.
90 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\""
91 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}"
92 |
93 | local basename
94 | basename="$(basename -s .dSYM "$source")"
95 | binary_name="$(ls "$source/Contents/Resources/DWARF")"
96 | binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}"
97 |
98 | # Strip invalid architectures so "fat" simulator / device frameworks work on device
99 | if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then
100 | strip_invalid_archs "$binary" "$warn_missing_arch"
101 | fi
102 |
103 | if [[ $STRIP_BINARY_RETVAL == 1 ]]; then
104 | # Move the stripped file into its final destination.
105 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\""
106 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.dSYM" "${DWARF_DSYM_FOLDER_PATH}"
107 | else
108 | # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing.
109 | touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM"
110 | fi
111 | fi
112 | }
113 |
114 | # Copies the bcsymbolmap files of a vendored framework
115 | install_bcsymbolmap() {
116 | local bcsymbolmap_path="$1"
117 | local destination="${BUILT_PRODUCTS_DIR}"
118 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}""
119 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"
120 | }
121 |
122 | # Signs a framework with the provided identity
123 | code_sign_if_enabled() {
124 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then
125 | # Use the current code_sign_identity
126 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
127 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'"
128 |
129 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
130 | code_sign_cmd="$code_sign_cmd &"
131 | fi
132 | echo "$code_sign_cmd"
133 | eval "$code_sign_cmd"
134 | fi
135 | }
136 |
137 | # Strip invalid architectures
138 | strip_invalid_archs() {
139 | binary="$1"
140 | warn_missing_arch=${2:-true}
141 | # Get architectures for current target binary
142 | binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)"
143 | # Intersect them with the architectures we are building for
144 | intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)"
145 | # If there are no archs supported by this binary then warn the user
146 | if [[ -z "$intersected_archs" ]]; then
147 | if [[ "$warn_missing_arch" == "true" ]]; then
148 | echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)."
149 | fi
150 | STRIP_BINARY_RETVAL=0
151 | return
152 | fi
153 | stripped=""
154 | for arch in $binary_archs; do
155 | if ! [[ "${ARCHS}" == *"$arch"* ]]; then
156 | # Strip non-valid architectures in-place
157 | lipo -remove "$arch" -output "$binary" "$binary"
158 | stripped="$stripped $arch"
159 | fi
160 | done
161 | if [[ "$stripped" ]]; then
162 | echo "Stripped $binary of architectures:$stripped"
163 | fi
164 | STRIP_BINARY_RETVAL=1
165 | }
166 |
167 | install_artifact() {
168 | artifact="$1"
169 | base="$(basename "$artifact")"
170 | case $base in
171 | *.framework)
172 | install_framework "$artifact"
173 | ;;
174 | *.dSYM)
175 | # Suppress arch warnings since XCFrameworks will include many dSYM files
176 | install_dsym "$artifact" "false"
177 | ;;
178 | *.bcsymbolmap)
179 | install_bcsymbolmap "$artifact"
180 | ;;
181 | *)
182 | echo "error: Unrecognized artifact "$artifact""
183 | ;;
184 | esac
185 | }
186 |
187 | copy_artifacts() {
188 | file_list="$1"
189 | while read artifact; do
190 | install_artifact "$artifact"
191 | done <$file_list
192 | }
193 |
194 | ARTIFACT_LIST_FILE="${BUILT_PRODUCTS_DIR}/cocoapods-artifacts-${CONFIGURATION}.txt"
195 | if [ -r "${ARTIFACT_LIST_FILE}" ]; then
196 | copy_artifacts "${ARTIFACT_LIST_FILE}"
197 | fi
198 |
199 | if [[ "$CONFIGURATION" == "Debug" ]]; then
200 | install_framework "${BUILT_PRODUCTS_DIR}/CoreDataEnvir/CoreDataEnvir.framework"
201 | fi
202 | if [[ "$CONFIGURATION" == "Release" ]]; then
203 | install_framework "${BUILT_PRODUCTS_DIR}/CoreDataEnvir/CoreDataEnvir.framework"
204 | fi
205 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
206 | wait
207 | fi
208 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-CoreDataEnvirSample/Pods-CoreDataEnvirSample-umbrella.h:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
14 | FOUNDATION_EXPORT double Pods_CoreDataEnvirSampleVersionNumber;
15 | FOUNDATION_EXPORT const unsigned char Pods_CoreDataEnvirSampleVersionString[];
16 |
17 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-CoreDataEnvirSample/Pods-CoreDataEnvirSample.debug.xcconfig:
--------------------------------------------------------------------------------
1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CoreDataEnvir"
2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
3 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CoreDataEnvir/CoreDataEnvir.framework/Headers"
4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
5 | OTHER_LDFLAGS = $(inherited) -framework "CoreData" -framework "CoreDataEnvir"
6 | PODS_BUILD_DIR = ${BUILD_DIR}
7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
8 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
9 | PODS_ROOT = ${SRCROOT}/Pods
10 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
11 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-CoreDataEnvirSample/Pods-CoreDataEnvirSample.modulemap:
--------------------------------------------------------------------------------
1 | framework module Pods_CoreDataEnvirSample {
2 | umbrella header "Pods-CoreDataEnvirSample-umbrella.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-CoreDataEnvirSample/Pods-CoreDataEnvirSample.release.xcconfig:
--------------------------------------------------------------------------------
1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CoreDataEnvir"
2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
3 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CoreDataEnvir/CoreDataEnvir.framework/Headers"
4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
5 | OTHER_LDFLAGS = $(inherited) -framework "CoreData" -framework "CoreDataEnvir"
6 | PODS_BUILD_DIR = ${BUILD_DIR}
7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
8 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
9 | PODS_ROOT = ${SRCROOT}/Pods
10 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
11 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-CoreDataEnvirSampleTests/Pods-CoreDataEnvirSampleTests-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | ${PRODUCT_BUNDLE_IDENTIFIER}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ${PRODUCT_NAME}
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-CoreDataEnvirSampleTests/Pods-CoreDataEnvirSampleTests-acknowledgements.markdown:
--------------------------------------------------------------------------------
1 | # Acknowledgements
2 | This application makes use of the following third party libraries:
3 | Generated by CocoaPods - https://cocoapods.org
4 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-CoreDataEnvirSampleTests/Pods-CoreDataEnvirSampleTests-acknowledgements.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreferenceSpecifiers
6 |
7 |
8 | FooterText
9 | This application makes use of the following third party libraries:
10 | Title
11 | Acknowledgements
12 | Type
13 | PSGroupSpecifier
14 |
15 |
16 | FooterText
17 | Generated by CocoaPods - https://cocoapods.org
18 | Title
19 |
20 | Type
21 | PSGroupSpecifier
22 |
23 |
24 | StringsTable
25 | Acknowledgements
26 | Title
27 | Acknowledgements
28 |
29 |
30 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-CoreDataEnvirSampleTests/Pods-CoreDataEnvirSampleTests-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_Pods_CoreDataEnvirSampleTests : NSObject
3 | @end
4 | @implementation PodsDummy_Pods_CoreDataEnvirSampleTests
5 | @end
6 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-CoreDataEnvirSampleTests/Pods-CoreDataEnvirSampleTests-umbrella.h:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
14 | FOUNDATION_EXPORT double Pods_CoreDataEnvirSampleTestsVersionNumber;
15 | FOUNDATION_EXPORT const unsigned char Pods_CoreDataEnvirSampleTestsVersionString[];
16 |
17 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-CoreDataEnvirSampleTests/Pods-CoreDataEnvirSampleTests.debug.xcconfig:
--------------------------------------------------------------------------------
1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
2 | PODS_BUILD_DIR = ${BUILD_DIR}
3 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
4 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
5 | PODS_ROOT = ${SRCROOT}/Pods
6 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
7 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-CoreDataEnvirSampleTests/Pods-CoreDataEnvirSampleTests.modulemap:
--------------------------------------------------------------------------------
1 | framework module Pods_CoreDataEnvirSampleTests {
2 | umbrella header "Pods-CoreDataEnvirSampleTests-umbrella.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-CoreDataEnvirSampleTests/Pods-CoreDataEnvirSampleTests.release.xcconfig:
--------------------------------------------------------------------------------
1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
2 | PODS_BUILD_DIR = ${BUILD_DIR}
3 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
4 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
5 | PODS_ROOT = ${SRCROOT}/Pods
6 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | CoreDataEnvir (since 2011-05-25) latest version 0.4
2 | =============
3 |
4 | CoreDataEnvir is a CoreData wrapper which use CoreData in convient way and supply thread safe in concurrenct programming. You can use it concurrenctly,run seperate CoreDataEnvir instance on one thread.
5 |
6 | ## First step:
7 |
8 | Register your data base file name
9 |
10 | ```Objective-C
11 | [CoreDataEnvir registerDatabaseFileName:@"db.sqlite"];
12 | ```
13 |
14 | Register your model file name(no file extension name)
15 |
16 | ```Objective-C
17 | [CoreDataEnvir registerModelFileName:@"SampleModel"];
18 | ```
19 |
20 | ## Simple data base access:
21 |
22 | Let's assumption the `Book` class is a model which represent a book object in your reading app. It has some field are `name`, `author` ... etc.
23 |
24 | There is an author "John Stevens Cabot Abbott" written a book named "Napoleon Bonnaparte".
25 |
26 | ### Add new record
27 |
28 | ```Objective-C
29 |
30 | [Book insertItemWithFillingBlock:^(id item) {
31 | item.name = @"CoreData tutorial";
32 | item.author = @"Headwindx";
33 | }];
34 |
35 | ```
36 |
37 | ### Fetch lots of records
38 |
39 | ```Objective-C
40 | //Find all books of John Stevens Cabot Abbott.
41 | NSArray *books= [Feed itemsWithFormat:@"author = %@", @"John Stevens Cabot Abbott"];
42 |
43 | ```
44 |
45 | ### Fetch one record
46 |
47 | ```Objective-C
48 | //Find one book model object.
49 | Book *book = [Book lastItemWithFormat:@"name = %@ && author = %@", @"Napoleon Bonnaparte", @"John Stevens Cabot Abbott"];
50 |
51 | ```
52 |
53 | ### Delete one record
54 |
55 | ```Objective-C
56 | [CoreDataEnvir asyncMainInBlock:^(CoreDataEnvir *db) {
57 | [db deleteDataItem:book];
58 | }];
59 |
60 | ```
61 |
62 | ### Delete records
63 |
64 | ```Objective-C
65 | [CoreDataEnvir asyncMainInBlock:^(CoreDataEnvir *db) {
66 | [db deleteDataItemSet:books];
67 | }];
68 | ```
69 |
70 | ## Concurrenct programming:
71 |
72 | ### On main thread
73 |
74 | You can do some lightweight operation on main thread. All of above operation must runs on main thread by default or it will raise an exception by `CoreDataEnvir`. So you should be carefully.
75 |
76 | #### You also can explicit use on main thread
77 |
78 | It makes you feel more safe :-)
79 |
80 | ```Objective-C
81 | [CoreDataEnvir asyncMainInBlock:^(CoreDataEnvir *db) {
82 | [Book insertItemWithFillingBlock:^(id item) {
83 | item.name = @"CoreData tutorial";
84 | item.author = @"Headwindx";
85 | }];
86 | }];
87 | ```
88 |
89 | ### On background thread
90 |
91 | It's already prepared a background GCD queue for you in `CoreDataEnvir`.
92 |
93 | The block `asyncBackgroundInBlock` will save memory cache to db file after `void(^)(CoreDataEnvir *db)` works finished.
94 |
95 | You don't need to use `[db saveDataBase];` like older version.
96 |
97 | ```Objective-C
98 |
99 | [CoreDataEnvir asyncBackgroundInBlock:^(CoreDataEnvir *db) {
100 | [Book insertItemOnBackgroundWithFillingBlock:^(id item) {
101 | item.name = @"CoreData tutorial";
102 | item.author = @"Headwindx";
103 | }];
104 | }];
105 |
106 | ```
107 |
108 | It becomes more conveniently on concurrenct programming.
109 |
110 | ### Convenient methods
111 |
112 | Must run on main queue:
113 |
114 |
115 | * `+ (void)asyncMainInBlock:(void(^)(CoreDataEnvir *db))CoreDataBlock;`
116 | * `+ (id)insertItemWithFillingBlock:(void(^)(id item))fillingBlock;`
117 | * `+ (NSArray *)itemsWithFormat:(NSString *)fmt,...;`
118 | ...
119 |
120 | Must run on background queue, you can use these APIs and some methods name within `Background`:
121 |
122 | * `+ (void)asyncBackgroundInBlock:(void(^)(CoreDataEnvir *db))CoreDataBlock;`
123 | * `+ (id)insertItemOnBackgroundWithFillingBlock:(void(^)(id item))fillingBlock;`
124 | * `+ (NSArray *)itemsOnBackgroundWithFormat:(NSString *)fmt,...;`
125 | ...
126 |
127 | Or you wanna run some operation in your own dispatch queue, you can choose this APIs:
128 |
129 | * `+ (CoreDataEnvir *)createInstance;` you'd better hold this instance for future.
130 | * `- (void)asyncInBlock:(void(^)(CoreDataEnvir *db))CoreDataBlock;`
131 |
132 | ## If your are newcomer to CoreData, please obey the rules below:
133 |
134 | * If you wanna keep you NSManagedObject objects, you shouldn't release you CoreDataEnvir object or it will be fault.
135 |
136 | * If you operate database in multiple threads, you should make sure you have one NSManagedObjectContext in seperate thread or GCD queue. Or it will occur conflict while one thread reading data and other one thread is writing data.
137 |
138 | > PS: So, in CoreDataEnvir please make sure your NSManagedObject object reference fetched from [CoreDataEnvir mainInstance] on main thread or from [CoreDataEnvir backgroundInstance] on background thread supplied by CoreDataEnvir and which never be released until application exist and it's enough for usual.
139 |
140 |
141 | [](https://bitdeli.com/free "Bitdeli Badge")
142 |
143 |
--------------------------------------------------------------------------------
/README_zh.md:
--------------------------------------------------------------------------------
1 | CoreDataEnvir (since 2011-05-25) latest version 0.4
2 | =============
3 |
4 | CoreDataEnvir 是一个 CoreData 框架的封装。提供了一种简单的方式来使用 CoreData ,它也为你的并发编程提供了线程安全支持。你可以在每个线程上运行一个单独的实例来进行并发编程。
5 |
6 | ## 第一步:
7 |
8 | 注册你的数据库文件名
9 |
10 | ```Objective-C
11 | [CoreDataEnvir registDatabaseFileName:@"db.sqlite"];
12 | ```
13 |
14 | 注册你的模型文件名(不包含文件扩展名)
15 |
16 | ```Objective-C
17 | [CoreDataEnvir registModelFileName:@"SampleModel"];
18 | ```
19 |
20 | ## 简单的数据库访问:
21 |
22 | 我们假设 `Book` 类是你的App中一个代表书籍对象的模型类。它有一些成员域 `name`, `author` 等等。
23 |
24 | 还有一个叫 "约翰史蒂芬" 的作者,写了一本传记叫 "拿破仑"
25 |
26 | ### 添加一个新记录
27 |
28 | ```Objective-C
29 |
30 | [Book insertItemWithFillingBlock:^(id item) {
31 | item.name = @"约翰史蒂芬";
32 | item.author = @"拿破仑";
33 | }];
34 |
35 | ```
36 |
37 | ### 查询一批记录
38 |
39 | ```Objective-C
40 | //查询 约翰史蒂芬 写得所有书籍
41 | NSArray *books= [Feed itemsWithFormat:@"author = %@", @"约翰史蒂芬"];
42 |
43 | ```
44 |
45 | ### 查询一条记录
46 |
47 | ```Objective-C
48 | //查找约翰史蒂芬写的拿破仑传记
49 | Book *book = [Book lastItemWithFormat:@"name = %@ && author = %@", @"拿破仑", @"约翰史蒂芬"];
50 |
51 | ```
52 |
53 | ### 删除一条记录
54 |
55 | ```Objective-C
56 | [CoreDataEnvir asyncMainInBlock:^(CoreDataEnvir *db) {
57 | [db deleteDataItem:book];
58 | }];
59 |
60 | ```
61 |
62 | ### 删除多条记录
63 |
64 | ```Objective-C
65 | [CoreDataEnvir asyncMainInBlock:^(CoreDataEnvir *db) {
66 | [db deleteDataItemSet:books];
67 | }];
68 | ```
69 |
70 | ## 并发编程:
71 |
72 | ### On main thread
73 |
74 | 你可以在主线程上做一些轻量级的操作,但最好不要影响到你的UI响应。所有以上介绍的数据操作,默认都是必须运行在主线程上的,否则 CoreDataEnvir 自己会主动抛出异常。所以你要注意这方面的使用,如果你不确定当前是否主线程,可以这么做:
75 |
76 | #### 你也可以明确地在主线程上使用 CoreDataEnvir
77 |
78 | 这样会让你感到比较有底一些:
79 |
80 | ```Objective-C
81 | [CoreDataEnvir asyncMainInBlock:^(CoreDataEnvir *db) {
82 | [Book insertItemWithFillingBlock:^(id item) {
83 | item.name = @"拿破仑";
84 | item.author = @"约翰史蒂芬";
85 | }];
86 | }];
87 | ```
88 |
89 | ### 在后台线程
90 |
91 | CoreDataEnvir 也准备了一个后台 GCD 队列供你使用。
92 |
93 | Block `asyncBackgroundInBlock` 将会在 `void(^)(CoreDataEnvir *db)` 调用结束后,自动将变动保存到数据库中。
94 |
95 | 你不必像老版本一样直接调用 `[db saveDataBase];` 。
96 |
97 | ```Objective-C
98 |
99 | [CoreDataEnvir asyncBackgroundInBlock:^(CoreDataEnvir *db) {
100 | [Book insertItemOnBackgroundWithFillingBlock:^(id item) {
101 | item.name = @"拿破仑";
102 | item.author = @"约翰史蒂芬";
103 | }];
104 | }];
105 |
106 | ```
107 |
108 | 这样在并发编程中 CoreData 的使用变得更加方便了。
109 |
110 | ### 几个快捷方法
111 |
112 | 必须在 GCD 主队列上运行:
113 |
114 |
115 | * `+ (void)asyncMainInBlock:(void(^)(CoreDataEnvir *db))CoreDataBlock;`
116 | * `+ (id)insertItemWithFillingBlock:(void(^)(id item))fillingBlock;`
117 | * `+ (NSArray *)itemsWithFormat:(NSString *)fmt,...;`
118 | ...
119 |
120 | 必须在后台 GCD 队列上运行,你可以使用这些方法名称中包含 `Background` 的API:
121 |
122 | * `+ (void)asyncBackgroundInBlock:(void(^)(CoreDataEnvir *db))CoreDataBlock;`
123 | * `+ (id)insertItemOnBackgroundWithFillingBlock:(void(^)(id item))fillingBlock;`
124 | * `+ (NSArray *)itemsOnBackgroundWithFormat:(NSString *)fmt,...;`
125 | ...
126 |
127 | 或者你想运行在你自己的 GCD 队列上,你可以选择这些 API:
128 |
129 | * `+ (CoreDataEnvir *)createInstance;` you'd better hold this instance for future.
130 | * `- (void)asyncInBlock:(void(^)(CoreDataEnvir *db))CoreDataBlock;`
131 |
132 | ## 如果你是一个 CoreData 新人,请遵守以下军规:
133 |
134 | * 如果你想以后使用你的 NSManagedObject 对象,你不要释放 CoreDataEnvir 对象,否则模型对象都将失效。
135 |
136 | * 如果你想在多线程上操作数据库,一定要确保每个线程有自己独立的 NSManagedObjectContext 对象。
137 |
138 | > PS:在 CoreDataEnvir 中,请确保你的 NSManagedObject 对象是在主线程上从 [CoreDataEnvir mainInstance] 中获取的对象,或者在后台线程上从 [CoreDataEnvir backgroundInstance] 得到的对象。这两个对象是不会被释放的,通常情况下,CoreDataEnvir 提供的两个线程就能应付常见的并发情况了。
139 |
--------------------------------------------------------------------------------
/Team+CoreDataClass.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Team+CoreDataClass.swift
3 | //
4 | //
5 | // Created by NicholasXu on 2020/9/14.
6 | //
7 | //
8 |
9 | import Foundation
10 | import CoreData
11 | import CoreDaaEnvir
12 |
13 | @objc(Team)
14 | public class Team: NSManagedObject {
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/Team+CoreDataProperties.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Team+CoreDataProperties.swift
3 | //
4 | //
5 | // Created by NicholasXu on 2020/9/14.
6 | //
7 | //
8 |
9 | import Foundation
10 | import CoreData
11 |
12 |
13 | extension Team {
14 |
15 | @nonobjc public class func fetchRequest() -> NSFetchRequest {
16 | return NSFetchRequest(entityName: "Team")
17 | }
18 |
19 | @NSManaged public var name: String?
20 | @NSManaged public var number: NSNumber?
21 | @NSManaged public var members: NSSet?
22 |
23 | }
24 |
25 | // MARK: Generated accessors for members
26 | extension Team {
27 |
28 | @objc(addMembersObject:)
29 | @NSManaged public func addToMembers(_ value: Member)
30 |
31 | @objc(removeMembersObject:)
32 | @NSManaged public func removeFromMembers(_ value: Member)
33 |
34 | @objc(addMembers:)
35 | @NSManaged public func addToMembers(_ values: NSSet)
36 |
37 | @objc(removeMembers:)
38 | @NSManaged public func removeFromMembers(_ values: NSSet)
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/backup.sh:
--------------------------------------------------------------------------------
1 | git add --all
2 | git commit -m "update"
3 | git push local master && git push origin master
4 |
--------------------------------------------------------------------------------
/build.sh:
--------------------------------------------------------------------------------
1 |
2 | xcodebuild -scheme CoreDataEnvir -configuration Release -sdk iphonesimulator -arch i386 -arch x86_64 clean build CONFIGURATION_BUILD_DIR=./build/iphonesimulator
3 | xcodebuild -scheme CoreDataEnvir -configuration Release -sdk iphoneos clean build CONFIGURATION_BUILD_DIR=./build/iphoneos
4 |
5 | cp -rf ./build/iphonesimulator/CoreDataEnvir.framework ./build/CoreDataEnvir.framework
6 |
7 | lipo -create ./build/iphoneos/CoreDataEnvir.framework/CoreDataEnvir ./build/CoreDataEnvir.framework/CoreDataEnvir -o ./build/CoreDataEnvir.framework/CoreDataEnvir
--------------------------------------------------------------------------------
/check:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | pod spec lint
3 |
--------------------------------------------------------------------------------
/podupdate.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | #不检查 cocoapods 数据库,直接更新内部模块
3 |
4 | mode=$1
5 |
6 | if [ -z $mode ]
7 | then
8 | mode="update --no-repo-update"
9 | elif [ $mode == "u" ]
10 | then
11 | mode="update --no-repo-update"
12 | elif [ $mode == "i" ]
13 | then
14 | mode="install --no-repo-update"
15 | elif [ $mode == "c" ]
16 | then
17 | rm -rf *.xcworkspace
18 | rm -rf Pods/
19 | rm Podfile.lock
20 | echo "Clear pod generated files."
21 | exit 0
22 | else
23 | echo "usage:"
24 | echo "./podupdate.sh i [\"for installing new libs\"]"
25 | echo "./podupdate.sh u [\"for updating exist libs\"]"
26 | exit 0
27 | fi
28 |
29 | echo $mode
30 |
31 | pod $mode
32 |
--------------------------------------------------------------------------------
/push2pods:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | pod trunk push CoreDataEnvir.podspec --verbose
4 |
--------------------------------------------------------------------------------
/pushtag:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | tagn=0.4
4 |
5 | xpush c "$1" && git push local --all && git tag -f "$tagn" && git push -f local "$tagn"
6 |
--------------------------------------------------------------------------------
/src/CoreDataEnvir/CoreDataEnvir.h:
--------------------------------------------------------------------------------
1 | //
2 | // CoreDataEnvir.h
3 | // CoreDataLab
4 | //
5 | // CoreData enviroment light wrapper.
6 | // Support CoreData operating methods.
7 | //
8 | // Create record item.
9 | // Support concurrency operating.
10 | //
11 | // Created by NicholasXu on 11-5-25.
12 | //
13 | // mailto:dehengxu@outlook.com
14 | //
15 | // Copyright 2011 NicholasXu. All rights reserved.
16 | //
17 |
18 |
19 | #import
20 | #import
21 |
22 | //#ifndef __CoreDataEnvir__
23 | //#define __CoreDataEnvir__
24 |
25 | #define CORE_DATA_ENVIR_SHOW_LOG 0
26 |
27 | @protocol CoreDataRescureDelegate;
28 |
29 | //! Project version number for CoreDataEnvir.
30 | FOUNDATION_EXPORT double CoreDataEnvirVersionNumber;
31 |
32 | //! Project version string for CoreDataEnvir.
33 | FOUNDATION_EXPORT const unsigned char CoreDataEnvirVersionString[];
34 |
35 | NS_ASSUME_NONNULL_BEGIN
36 |
37 | #pragma mark - CoreDataEnvirement
38 |
39 | typedef enum
40 | {
41 | CDEErrorInstanceCreateTooMutch = 1000,
42 | CDEErrorModelFileNotFound = 1001
43 | }CoreDataEnvirError;
44 |
45 | extern NSString* const CDE_DOMAIN;
46 |
47 | @interface CoreDataEnvir : NSObject {
48 | NSRecursiveLock *__recursiveLock;
49 | }
50 |
51 | /// Current work queue
52 | #if OS_OBJECT_USE_OBJC
53 | @property (nonatomic, strong) dispatch_queue_t currentQueue;
54 | #else
55 | @property (nonatomic, assign) dispatch_queue_t currentQueue;
56 | #endif
57 |
58 | /**
59 | A model object.
60 | */
61 | @property (nonatomic, readonly) NSManagedObjectModel *model;
62 |
63 | /**
64 | A context object.
65 | */
66 | @property (nonatomic, readonly) NSManagedObjectContext *context;
67 |
68 | /**
69 | A persistance coordinator object.
70 | */
71 | @property (nonatomic, strong) NSPersistentStoreCoordinator *persistentStoreCoordinator;
72 |
73 | /**
74 | A NSFetchedResultsController object, not be used by now.
75 | */
76 | @property (nonatomic, strong) NSFetchedResultsController * fetchedResultsCtrl;
77 |
78 | /**
79 | Register resucrer, recommend using UIApplicationDelegate instance.
80 | */
81 | @property (class, nonatomic, weak) id rescureDelegate;
82 |
83 | #pragma mark - Initialization
84 |
85 | /**
86 | Creating main instance if current thread is main thread else return an background instance.
87 | */
88 | + (CoreDataEnvir *)instance;
89 |
90 | /**
91 | Creating a new instance by default db, momd file name.
92 | */
93 | + (CoreDataEnvir *)createInstance;
94 |
95 | #pragma mark - Handle data store
96 |
97 | /**
98 | Save
99 | */
100 | - (BOOL)saveDataBase;
101 |
102 | - (BOOL)saveForConfiguration:(NSString*)name;
103 |
104 | /**
105 | Operating on NSManagedObject
106 | */
107 | - (id)dataItemWithID:(NSManagedObjectID *)objectId;
108 | - (id)updateDataItem:(NSManagedObject *)object;
109 | - (BOOL)deleteDataItem:(NSManagedObject *)aItem;
110 | - (BOOL)deleteDataItemSet:(NSSet *)aItemSet;
111 | - (BOOL)deleteDataItems:(NSArray*)items;
112 |
113 | #pragma mark - Observing context
114 |
115 | /**
116 | Add observing for concurrency.
117 | */
118 | - (void)registerObserving;
119 |
120 | /**
121 | * Remove observer.
122 | */
123 | - (void)unregisterObserving;
124 |
125 |
126 | #pragma mark - Work queue relevant
127 |
128 | /// run block asynchronously without saving context
129 | /// @param CoreDataBlock A block passing CoreDataEnvir instance
130 | - (void)asyncWithBlock:(void(^)(CoreDataEnvir *db))CoreDataBlock;
131 |
132 | /// run block synchronously without saving context
133 | /// @param CoreDataBlock A block passing CoreDataEnvir instance
134 | - (void)syncWithBlock:(void(^)(CoreDataEnvir *db))CoreDataBlock;
135 |
136 | #pragma mark - NewAPIs initialization
137 |
138 | typedef void(^CoreDataEnvirBlock)(CoreDataEnvir* _Nonnull);
139 |
140 | /// Create instance with private work queue
141 | + (instancetype)create;
142 |
143 | /// Create instance and bind work queue with main queue
144 | + (instancetype)createMain;
145 |
146 | #pragma mark - NewAPIs setup CoreData requires
147 |
148 | /// Setup CoreData with reusable block
149 | /// @param config Block
150 | - (instancetype)setupWithBlock:(CoreDataEnvirBlock _Nonnull)config;
151 |
152 | /// Setup model and context
153 | /// @param fileURL model path
154 | - (instancetype)setupModelWithURL:(NSURL*)fileURL;
155 |
156 | /// Setup persistent with default configuration
157 | /// @param fileURL Store file path
158 | - (instancetype)setupDefaultPersistentStoreWithURL:(NSURL*)fileURL;
159 |
160 | /// Setup persistent for configuration
161 | /// @param fileURL Store file path
162 | /// @param name Configuration
163 | - (instancetype)setupPersistentStoreWithURL:(NSURL*)fileURL forConfiguration:(NSString* _Nullable)name;
164 |
165 | /// Return persistent store from persistent store coordinator
166 | /// @param fileURL Persistent store location
167 | - (NSPersistentStore*)persistentStoreForURL:(NSURL*)fileURL;
168 |
169 | /// Return persistent store from persistent store coordinator
170 | /// @param name Configuration
171 | - (NSPersistentStore*)persistentStoreForConfiguration:(NSString*)name;
172 |
173 | @end
174 |
175 | #pragma mark - NSPersistentStoreCoordinator
176 |
177 | @interface NSPersistentStoreCoordinator (CoreDataEnvir)
178 |
179 | /// Return persistent store from persistent store coordinator
180 | /// @param name Configuration
181 | - (NSPersistentStore *)persistentStoreForConfiguration:(NSString *)name;
182 |
183 | @end
184 |
185 | NS_ASSUME_NONNULL_END
186 |
187 | //#endif
188 |
189 |
--------------------------------------------------------------------------------
/src/CoreDataEnvir/CoreDataEnvir.m:
--------------------------------------------------------------------------------
1 | //
2 | // CoreDataEnvir.m
3 | // CoreDataLab
4 | //
5 | // Created by NicholasXu on 11-5-25.
6 | // Copyright 2011 NicholasXu. All rights reserved.
7 | //
8 |
9 | #import "CoreDataEnvir.h"
10 |
11 | #import "CoreDataEnvir_Private.h"
12 | #import "CoreDataEnvir_Main.h"
13 | #import "CoreDataEnvirObserver.h"
14 | #import "CoreDataRescureDelegate.h"
15 | #import "CoreDataEnvirDescriptor.h"
16 |
17 | // debug
18 | #if __has_include("NSManagedObject_Debug.h")
19 | #import "NSManagedObject_Debug.h"
20 | #import "NSObject_Debug.h"
21 | #endif
22 |
23 | // NSManagedObeject
24 | #import "NSManagedObject_Convenient.h"
25 | #import "NSManagedObject_MainThread.h"
26 | #import "NSManagedObject_Background.h"
27 |
28 | /**
29 | Do not use any lock method to protect thread resources in CoreData under concurrency condition!
30 | */
31 | #define CONTEXT_LOCK_BEGIN do {\
32 | BOOL _isLocked = [context tryLock];\
33 | if (_isLocked) {\
34 |
35 | #define CONTEXT_LOCK_END [context unlock];\
36 | break;\
37 | }\
38 | } while(0);
39 |
40 | #define LOCK_BEGIN [recursiveLock lock];
41 | #define LOCK_END [recursiveLock unlock];
42 |
43 | NSString* const CDE_DOMAIN = @"com.dehengxu.CoreDataEnvir";
44 |
45 | NSString* const kDEFAULT_CONFIGURATION_NAME = @"PF_DEFAULT_CONFIGURATION_NAME";
46 |
47 | static NSString *_default_model_name = nil;
48 | static NSString *_default_model_dir = nil;
49 | static NSString *_default_db_dir = nil;
50 | static NSString *_default_db_file_name = nil;
51 | static dispatch_semaphore_t _sem_main = NULL;
52 |
53 | #pragma mark - CoreDataEnvir implementation
54 |
55 | @interface CoreDataEnvir ()
56 | #pragma mark - rewrite property
57 |
58 | /// Current work queue
59 | //@property (nonatomic, strong) dispatch_queue_t currentQueue;
60 |
61 | /**
62 | A model object.
63 | */
64 | @property (nonatomic, strong) NSManagedObjectModel *model;
65 |
66 | /**
67 | A context object.
68 | */
69 | @property (nonatomic, strong) NSManagedObjectContext *context;
70 |
71 | @property (nonatomic, strong) NSMutableDictionary* persistentStoreCacheForName;
72 |
73 | @end
74 |
75 | @implementation CoreDataEnvir
76 |
77 | + (id)rescureDelegate {
78 | return _rescureDelegate;
79 | }
80 |
81 | + (void)setRescureDelegate:(id)rescureDelegate {
82 | _rescureDelegate = rescureDelegate;
83 | }
84 |
85 | #pragma mark - Initialization
86 |
87 | + (void)initialize
88 | {
89 | // Default db dir is document
90 | _default_db_dir = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] copy];
91 | _default_db_file_name = @"db.sqlite";
92 | _default_model_name = @"Model";
93 | _sem_main = dispatch_semaphore_create(1l);
94 | }
95 |
96 | + (void)registerRescureDelegate:(id)delegate
97 | {
98 | _rescureDelegate = delegate;
99 | }
100 |
101 | #pragma mark - instance handle
102 |
103 | + (CoreDataEnvir *)instance
104 | {
105 | dispatch_semaphore_wait(_sem_main, ~0ull);
106 | CoreDataEnvir *db = nil;
107 | if ([[NSThread currentThread] isMainThread]) {
108 | db = [self mainInstance];
109 | }else {
110 | db = [self createInstance];
111 | }
112 | dispatch_semaphore_signal(_sem_main);
113 |
114 | return db;
115 | }
116 |
117 | + (CoreDataEnvir *)createInstance
118 | {
119 | CoreDataEnvir *cde = [CoreDataEnvirDescriptor.defaultInstance instance]; //[[self alloc] initWithDatabaseFileName:nil modelFileName:nil];
120 | return cde;
121 | }
122 |
123 | - (instancetype)init {
124 | self = [super init];
125 | if (self) {
126 | _create_counter ++;
127 | __recursiveLock = [[NSRecursiveLock alloc] init];
128 | _persistentStoreCacheForName = @{}.mutableCopy;
129 | }
130 | return self;
131 | }
132 |
133 | - (void)dealloc {
134 | #if DEBUG && CORE_DATA_ENVIR_SHOW_LOG
135 | NSLog(@"%@", [self currentDispatchQueueLabel]);
136 | #endif
137 | _create_counter --;
138 | NSAssert(_create_counter >=0, @"over dealloc. %ld", _create_counter);
139 | #if DEBGU && CORE_DATA_ENVIR_SHOW_LOG
140 | NSLog(@"%s\ncreate counter :%d\n\n", __func__, _create_counter);
141 | #endif
142 | [self unregisterObserving];
143 | }
144 |
145 | #pragma mark - Handle data store
146 |
147 | - (BOOL)saveDataBase
148 | {
149 | if (![self.context hasChanges]) {
150 | NSLog(@"Context no changed.");
151 | return YES;
152 | }
153 | __block BOOL bResult = NO;
154 | #pragma clang push
155 | #pragma clang diagnostic ignored "-Wdeprecated-declarations"
156 |
157 | void(^doWork)(void) = ^ {
158 | NSError *error = nil;
159 | bResult = [self.context save:&error];
160 |
161 | if (!bResult) {
162 | if (error != nil) {
163 | NSLog(@"%s, %d, error:%@", __PRETTY_FUNCTION__, __LINE__, error);
164 | }
165 | //Do we need rollback?
166 | //[context rollback];
167 | }
168 | };
169 |
170 | if ([[UIDevice currentDevice] systemVersion].floatValue >= 8.0) {
171 | [self.persistentStoreCoordinator performBlockAndWait:doWork];
172 | }else {
173 | [self.persistentStoreCoordinator lock];
174 | doWork();
175 | [self.persistentStoreCoordinator unlock];
176 | }
177 | #pragma clang pop
178 |
179 | #if DEBGU && CORE_DATA_ENVIR_SHOW_LOG
180 | NSLog(@"%s", __FUNCTION__);
181 | #endif
182 | return bResult;
183 | }
184 |
185 | - (BOOL)saveForConfiguration:(NSString *)name {
186 | return NO;
187 | }
188 |
189 | #pragma mark - Data handling
190 |
191 | - (id)dataItemWithID:(NSManagedObjectID *)objectId
192 | {
193 | if (objectId && self.context) {
194 |
195 | NSManagedObject *item = nil;
196 |
197 | @try {
198 | item = [self.context objectWithID:objectId];
199 | }
200 | @catch (NSException *exception) {
201 | NSLog(@"exce :%@", [exception description]);
202 | item = nil;
203 | }
204 | @finally {
205 |
206 | }
207 |
208 | return item;
209 | }
210 | return nil;
211 | }
212 |
213 | - (id)updateDataItem:(NSManagedObject *)object
214 | {
215 | if (object.isFault) {
216 | return [self dataItemWithID:object.objectID];
217 | }
218 | return object;
219 | }
220 |
221 | - (BOOL)deleteDataItem:(NSManagedObject *)object
222 | {
223 | if (!object) {
224 | return NO;
225 | }
226 |
227 | NSManagedObject *getObject = object;
228 | if (object.isFault) {
229 | getObject = [self dataItemWithID:object.objectID];
230 | }
231 | #if DEBUG && CORE_DATA_ENVIR_SHOW_LOG
232 | NSLog(@"%s objectID :%@; getObject :%@;", __FUNCTION__, aItem.objectID, getObject);
233 | #endif
234 |
235 | if (getObject) {
236 | @try {
237 | [self.context deleteObject:getObject];
238 | }
239 | @catch (NSException *exception) {
240 | NSLog(@"Deleting abort cause exce :%@", [exception description]);
241 | return NO;
242 | }
243 | @finally {
244 |
245 | }
246 | }
247 | #if DEBUG && CORE_DATA_ENVIR_SHOW_LOG
248 | NSLog(@"delete finished!");
249 | #endif
250 |
251 | return YES;
252 | }
253 |
254 | - (BOOL) deleteDataItemSet:(NSSet *)aItemSet
255 | {
256 | for (NSManagedObject *obj in aItemSet) {
257 | [self deleteDataItem:obj];
258 | }
259 |
260 | return YES;
261 | }
262 |
263 | - (BOOL)deleteDataItems:(NSArray *)items
264 | {
265 | for (NSManagedObject *obj in items) {
266 | [self deleteDataItem:obj];
267 | }
268 |
269 | return YES;
270 | }
271 |
272 | #pragma mark - Obseving context
273 |
274 | - (void)registerObserving
275 | {
276 | #if DEBUG
277 | NSLog(@"%s", __FUNCTION__);
278 | #endif
279 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mergeChanges:) name:NSManagedObjectContextDidSaveNotification object:nil];
280 | }
281 |
282 | - (void)unregisterObserving
283 | {
284 | #if DEBUG
285 | NSLog(@"%s", __FUNCTION__);
286 | #endif
287 | [[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextDidSaveNotification object:nil];
288 | }
289 |
290 | #pragma mark - Work queue relevant
291 |
292 | - (void)asyncWithBlock:(void (^)(CoreDataEnvir *))CoreDataBlock
293 | {
294 | dispatch_async([self currentQueue], ^{
295 | CoreDataBlock(self);
296 | });
297 | }
298 |
299 | - (void)syncWithBlock:(void (^)(CoreDataEnvir *)) CoreDataBlock
300 | {
301 | if ([NSThread isMainThread] && self.currentQueue == dispatch_get_main_queue()) {
302 | CoreDataBlock(self);
303 | }else {
304 | dispatch_sync([self currentQueue], ^{
305 | CoreDataBlock(self);
306 | });
307 | }
308 | }
309 |
310 | //+ (void)asyncMainInBlock:(void (^)(CoreDataEnvir *))CoreDataBlock
311 | //{
312 | // [[self mainInstance] asyncInBlock:CoreDataBlock];
313 | //}
314 | //
315 | //+ (void)asyncBackgroundInBlock:(void (^)(CoreDataEnvir *))CoreDataBlock
316 | //{
317 | // [[self backgroundInstance] asyncInBlock:CoreDataBlock];
318 | //}
319 |
320 | #pragma mark - NewAPIs
321 |
322 | + (instancetype)create {
323 | CoreDataEnvir* db = [CoreDataEnvir new];
324 | db.currentQueue = dispatch_queue_create([[NSString stringWithFormat:@"%@-%ld", [NSString stringWithUTF8String:"com.dehengxu.coredataenvir.background"], _create_counter] UTF8String], NULL);
325 | return db;
326 | }
327 |
328 | + (instancetype)createMain {
329 | CoreDataEnvir* db = [CoreDataEnvir new];
330 | db.currentQueue = dispatch_get_main_queue();
331 | return db;
332 | }
333 |
334 |
335 | #pragma mark - setup CoreData requires
336 |
337 | - (instancetype)setupWithBlock:(void (^)(CoreDataEnvir * _Nonnull))config {
338 | [self syncWithBlock:config];
339 | return self;
340 | }
341 |
342 | - (instancetype)setupModelWithURL:(NSURL *)fileURL {
343 | NSAssert(fileURL, @"fileURL must be non-null.");
344 | NSAssert(fileURL.isFileURL, @"fileURL must begin with file://");
345 | if (!fileURL || !fileURL.isFileURL) {
346 | return nil;
347 | }
348 |
349 | NSLog(@"model %d, url: %@", fileURL.isFileURL, fileURL.path);
350 | if (![NSFileManager.defaultManager fileExistsAtPath:fileURL.path isDirectory:NULL]) {
351 | NSAssert(false, @"fileURL does not exist: %@", fileURL.absoluteString);
352 | return nil;
353 | }
354 |
355 | self.model = [[NSManagedObjectModel alloc] initWithContentsOfURL:fileURL];
356 | if (!_context) {
357 | _context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
358 | }
359 | [self.context setRetainsRegisteredObjects:NO];
360 | [self.context setPropagatesDeletesAtEndOfEvent:NO];
361 | [self.context setMergePolicy:NSOverwriteMergePolicy];
362 |
363 | return self;
364 | }
365 |
366 | - (instancetype)setupDefaultPersistentStoreWithURL:(NSURL *)fileURL {
367 | if (!self.model) {
368 | NSAssert(false, @"Should initialize model prior");
369 | return nil;
370 | }
371 |
372 | if (!_persistentStoreCoordinator) {
373 | self.persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.model];
374 | }
375 | if (!self.persistentStoreCoordinator) {
376 | NSAssert(false, @"Create persistentStoreCoordinator failed");
377 | return nil;
378 | }
379 | [self.context setPersistentStoreCoordinator:self.persistentStoreCoordinator];
380 |
381 | [self registerObserving];
382 |
383 | if (![self setupPersistentStoreWithURL:fileURL forConfiguration:nil]) {
384 | return nil;
385 | }
386 |
387 | return self;
388 | }
389 |
390 | - (instancetype)setupPersistentStoreWithURL:(NSURL *)fileURL forConfiguration:(NSString *_Nullable)name {
391 |
392 | NSError* error = nil;
393 | [self.persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:name URL:fileURL options:[self defaultPersistentOptions] error:&error];
394 | if (error) {
395 | NSAssert(error, @"Add persistent store failed: %@", error);
396 | return nil;
397 | }
398 | NSLog(@"Add persistent store %@ to %@", name, fileURL);
399 |
400 | return self;
401 | }
402 |
403 | - (NSPersistentStore *)persistentStoreForURL:(NSURL *)fileURL {
404 | return [_persistentStoreCoordinator persistentStoreForURL:fileURL];
405 | }
406 |
407 | - (NSPersistentStore *)persistentStoreForConfiguration:(NSString *)name {
408 | id store = _persistentStoreCacheForName[name];
409 | if (store) { return store; }
410 | store = [_persistentStoreCoordinator persistentStoreForConfiguration:name];
411 | _persistentStoreCacheForName[name] = store; // over write cache
412 | return store;
413 | }
414 |
415 |
416 | @end
417 |
418 | #pragma mark - NSPersistentStoreCoordinator
419 |
420 | @implementation NSPersistentStoreCoordinator (CoreDataEnvir)
421 |
422 | - (NSPersistentStore *)persistentStoreForConfiguration:(NSString *)name {
423 | for (NSPersistentStore* persi in self.persistentStores) {
424 | if ([persi.configurationName isEqualToString:name]) {
425 | return persi;
426 | }
427 | }
428 | return nil;
429 | }
430 |
431 | @end
432 |
--------------------------------------------------------------------------------
/src/CoreDataEnvir/CoreDataEnvirDescriptor.h:
--------------------------------------------------------------------------------
1 | //
2 | // CoreDataEnvirDescriptor.h
3 | // CoreDataEnvirSample
4 | //
5 | // Created by Deheng Xu on 2020/9/19.
6 | // Copyright © 2020 Nicholas.Xu. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @class CoreDataEnvir;
14 |
15 | @interface CoreDataEnvirDescriptor : NSObject
16 |
17 | @property (class, nonatomic, readonly) CoreDataEnvirDescriptor* defaultInstance;
18 |
19 | @property (nonatomic, copy, nullable) NSString* modelName;
20 | @property (nonatomic, copy) NSString* storeFileName;
21 | @property (nonatomic, copy) NSString* storeDirectory;
22 | @property (nonatomic, copy, nullable) NSArray* storeURLs;
23 | @property (nonatomic, copy, nullable) NSArray* configurations;
24 | @property (nonatomic, strong) NSBundle* bundle;
25 |
26 | + (instancetype)instance;
27 |
28 | + (instancetype)instanceWithModelName:(NSString* _Nullable)modelName bundle:(NSBundle* _Nullable)bundle storeFileName:(NSString* _Nullable)fileName storedUnderDirectory:(NSString* _Nullable)directory;
29 |
30 | //- (instancetype) NS_DESIGNATED_INITIALIZER init;
31 |
32 | - (instancetype) NS_DESIGNATED_INITIALIZER initWithModelName:(NSString* _Nullable)modelName bundle:(NSBundle* _Nullable)bundle storeFileName:(NSString* _Nullable)fileName storedUnderDirectory:(NSString* _Nullable)directory;
33 |
34 | - (CoreDataEnvir*)mainInstance;
35 | - (CoreDataEnvir*)backgroundInstance;
36 | - (CoreDataEnvir*)instance;
37 |
38 | @end
39 |
40 | NS_ASSUME_NONNULL_END
41 |
--------------------------------------------------------------------------------
/src/CoreDataEnvir/CoreDataEnvirDescriptor.m:
--------------------------------------------------------------------------------
1 | //
2 | // CoreDataEnvirDescriptor.m
3 | // CoreDataEnvirSample
4 | //
5 | // Created by Deheng Xu on 2020/9/19.
6 | // Copyright © 2020 Nicholas.Xu. All rights reserved.
7 | //
8 |
9 | #import "CoreDataEnvirDescriptor.h"
10 | #import "CoreDataEnvir.h"
11 | #import "CoreDataEnvir_Private.h"
12 |
13 | @interface CoreDataEnvirDescriptor ()
14 | @end
15 |
16 | @implementation CoreDataEnvirDescriptor
17 |
18 | + (instancetype)defaultInstance {
19 | static dispatch_once_t onceToken = 0;
20 | static CoreDataEnvirDescriptor* __shared__ = nil;
21 | dispatch_once(&onceToken, ^{
22 | __shared__ = [[super alloc] init];
23 | __shared__.modelName = nil;//@"Model";
24 | __shared__.storeFileName = @"db.sqlite";
25 | __shared__.storeDirectory = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] copy];
26 | __shared__.bundle = NSBundle.mainBundle;
27 | });
28 | return __shared__;
29 | }
30 |
31 | + (instancetype)instance {
32 | return [self instanceWithModelName:nil bundle:nil storeFileName:nil storedUnderDirectory:nil];
33 | }
34 |
35 | + (instancetype)instanceWithModelName:(NSString *)modelName bundle:(NSBundle *)bundle storeFileName:(NSString *)fileName storedUnderDirectory:(NSString *)directory {
36 | CoreDataEnvirDescriptor* ins = [[CoreDataEnvirDescriptor alloc] initWithModelName:modelName bundle:bundle storeFileName:fileName storedUnderDirectory:directory];
37 | return ins;
38 | }
39 |
40 | - (instancetype)initWithModelName:(NSString *)modelName bundle:(NSBundle *)bundle storeFileName:(NSString *)fileName storedUnderDirectory:(NSString *)directory {
41 | self = [super init];
42 | if (self) {
43 | self.modelName = modelName ?: [self.class.defaultInstance modelName];
44 | self.storeFileName = fileName ?: self.class.defaultInstance.storeFileName;
45 | self.storeDirectory = directory ?: self.class.defaultInstance.storeDirectory;
46 | self.bundle = bundle ?: self.class.defaultInstance.bundle;
47 | }
48 | return self;
49 | }
50 |
51 | - (NSURL*)modelURL {
52 | NSURL* url = [self.bundle URLForResource:self.modelName withExtension:@"momd"];
53 | return url;
54 | }
55 |
56 | - (NSURL*)storeURL {
57 | NSURL* url = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/%@", self.storeDirectory, self.storeFileName]];
58 | return url;
59 | }
60 |
61 | - (CoreDataEnvir *)mainInstance {
62 |
63 | static dispatch_once_t onceToken;
64 | dispatch_once(&onceToken, ^{
65 | _mainInstance = [self generate];
66 | _mainInstance.currentQueue = dispatch_get_main_queue();
67 | });
68 |
69 | return _mainInstance;
70 | }
71 |
72 | - (CoreDataEnvir *)backgroundInstance {
73 |
74 | static dispatch_once_t onceToken;
75 | dispatch_once(&onceToken, ^{
76 | _backgroundInstance = [self instance];
77 | });
78 |
79 | return _backgroundInstance;
80 | }
81 |
82 | - (CoreDataEnvir*)generate {
83 | CoreDataEnvir* ins = [CoreDataEnvir new];
84 | [ins setupModelWithURL:[self modelURL]];
85 | [ins setupDefaultPersistentStoreWithURL:[self storeURL]];
86 | for (int i = 0; i < self.configurations.count; i++) {
87 | NSString* name = self.configurations[i];
88 | NSURL* url = [self storeURL];
89 |
90 | if (self.storeURLs.count) {
91 | url = [self.storeURLs objectAtIndex:i];
92 | }
93 |
94 | [ins setupPersistentStoreWithURL:url forConfiguration:name];
95 | }
96 | return ins;
97 | }
98 |
99 | - (CoreDataEnvir *)instance {
100 | CoreDataEnvir* ins = [self generate];
101 | if (ins && ![ins currentQueue] ) {
102 | ins.currentQueue = dispatch_queue_create([[NSString stringWithFormat:@"%@-%ld", [NSString stringWithUTF8String:"com.dehengxu.coredataenvir.background"], _create_counter] UTF8String], NULL);
103 | }
104 | return ins;
105 | }
106 |
107 | @end
108 |
--------------------------------------------------------------------------------
/src/CoreDataEnvir/CoreDataEnvirHeader.h:
--------------------------------------------------------------------------------
1 | //
2 | // CoreDataEnvirHeader.h
3 | // CoreDataEnvirSample
4 | //
5 | // Created by NicholasXu on 15/8/30.
6 | // Copyright (c) 2015年 Nicholas.Xu. All rights reserved.
7 | //
8 |
9 | #ifndef CoreDataEnvir_CoreDataEnvirHeader_h
10 | #define CoreDataEnvir_CoreDataEnvirHeader_h
11 |
12 | #import
13 | #import
14 | #import
15 | #import
16 |
17 | #import
18 | #import
19 | #import
20 |
21 | //! Project version number for CoreDataEnvir.
22 | FOUNDATION_EXPORT double CoreDataEnvirVersionNumber;
23 |
24 | //! Project version string for CoreDataEnvir.
25 | FOUNDATION_EXPORT const unsigned char CoreDataEnvirVersionString[];
26 |
27 | #endif
28 |
--------------------------------------------------------------------------------
/src/CoreDataEnvir/CoreDataEnvirObserver.h:
--------------------------------------------------------------------------------
1 | //
2 | // CoreDataEnvirObserver.h
3 | // CoreDataEnvirFramework
4 | //
5 | // Created by Deheng Xu on 2020/9/18.
6 | // Copyright © 2020 Nicholas.Xu. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | #pragma mark - CoreDataEnvirObserver (Not be used temporarily)
14 |
15 | @protocol CoreDataEnvirObserver
16 |
17 | @optional
18 | - (void)didFetchingFinished:(NSArray *) aItems;
19 | - (void)didUpdateContext:(id)sender;
20 | - (void)didDeleteObjects:(id)sender;
21 | - (void)didInsertObjects:(id)sender;
22 | - (void)didUpdateObjects:(id)sender;
23 |
24 | @end
25 |
26 |
27 |
28 | NS_ASSUME_NONNULL_END
29 |
--------------------------------------------------------------------------------
/src/CoreDataEnvir/CoreDataEnvir_Background.h:
--------------------------------------------------------------------------------
1 | //
2 | // CoreDataEnvir_Background.h
3 | // CoreDataEnvirSample
4 | //
5 | // Created by NicholasXu on 15/8/30.
6 | // Copyright (c) 2015年 Nicholas.Xu. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface CoreDataEnvir (CDEBackground)
15 |
16 | + (CoreDataEnvir *)backgroundInstance;
17 |
18 | + (dispatch_queue_t)backgroundQueue;
19 |
20 | @end
21 |
22 | NS_ASSUME_NONNULL_END
23 |
--------------------------------------------------------------------------------
/src/CoreDataEnvir/CoreDataEnvir_Background.m:
--------------------------------------------------------------------------------
1 | //
2 | // CoreDataEnvir_Background.m
3 | // CoreDataEnvirSample
4 | //
5 | // Created by NicholasXu on 15/8/30.
6 | // Copyright (c) 2015年 Nicholas.Xu. All rights reserved.
7 | //
8 |
9 | #import "CoreDataEnvir_Background.h"
10 | #import "CoreDataEnvirDescriptor.h"
11 |
12 | @implementation CoreDataEnvir (CDEBackground)
13 |
14 | + (CoreDataEnvir *)backgroundInstance
15 | {
16 | return [CoreDataEnvirDescriptor.defaultInstance backgroundInstance];
17 | }
18 |
19 | + (dispatch_queue_t)backgroundQueue
20 | {
21 | return [[CoreDataEnvir backgroundInstance] currentQueue];
22 | }
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/src/CoreDataEnvir/CoreDataEnvir_Main.h:
--------------------------------------------------------------------------------
1 | //
2 | // CoreDataEnvir_Main.h
3 | // CoreDataEnvirSample
4 | //
5 | // Created by NicholasXu on 15/8/31.
6 | // Copyright (c) 2015年 Nicholas.Xu. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import
12 |
13 | NS_ASSUME_NONNULL_BEGIN
14 |
15 | @interface CoreDataEnvir (CDEMain)
16 |
17 | /**
18 | Only returen a single instance runs on main thread.
19 | */
20 | + (CoreDataEnvir *)mainInstance;
21 |
22 | /**
23 | Main queue.
24 | */
25 | + (dispatch_queue_t)mainQueue;
26 |
27 | @end
28 |
29 | NS_ASSUME_NONNULL_END
30 |
--------------------------------------------------------------------------------
/src/CoreDataEnvir/CoreDataEnvir_Main.m:
--------------------------------------------------------------------------------
1 | //
2 | // CoreDataEnvir_Main.m
3 | // CoreDataEnvirSample
4 | //
5 | // Created by NicholasXu on 15/8/31.
6 | // Copyright (c) 2015年 Nicholas.Xu. All rights reserved.
7 | //
8 |
9 | #import "CoreDataEnvir_Main.h"
10 | #import "CoreDataEnvirDescriptor.h"
11 |
12 | @implementation CoreDataEnvir (CDEMain)
13 |
14 | + (CoreDataEnvir *)mainInstance
15 | {
16 | return [CoreDataEnvirDescriptor.defaultInstance mainInstance];
17 | }
18 |
19 | + (dispatch_queue_t)mainQueue
20 | {
21 | return [[CoreDataEnvir mainInstance] currentQueue];
22 | }
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/src/CoreDataEnvir/CoreDataRescureDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // CoreDataRescureDelegate.h
3 | // CoreDataEnvirFramework
4 | //
5 | // Created by Deheng Xu on 2020/9/18.
6 | // Copyright © 2020 Nicholas.Xu. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @class CoreDataEnvir;
14 |
15 | #pragma mark - CoreDataRescureDelegate
16 |
17 | /**
18 | CoreData rescure delegate.
19 | While core data envirement init fails occured.
20 | */
21 | @protocol CoreDataRescureDelegate
22 |
23 | @optional
24 |
25 | /**
26 | Reture if need rescure or abort directly.
27 | */
28 | - (BOOL)shouldRescureCoreData;
29 |
30 | /**
31 | Return if abort while rescure failed.
32 | */
33 | - (BOOL)shouldAbortWhileRescureFailed;
34 |
35 | /**
36 | Did start rescure core data.
37 |
38 | @param cde A CoreDataEnvir instance.
39 | */
40 | - (void)didStartRescureCoreData:(CoreDataEnvir *)cde;
41 |
42 | /**
43 | Did finished rescuring work.
44 |
45 | @param cde A CoreDataEnvir instance.
46 | */
47 | - (void)didFinishedRescuringCoreData:(CoreDataEnvir *)cde;
48 |
49 | /**
50 | Rescure failed.
51 |
52 | @param cde A CoreDataEnvir instance.
53 | */
54 | - (void)rescureFailed:(CoreDataEnvir *)cde;
55 |
56 | @end
57 |
58 |
59 |
60 | NS_ASSUME_NONNULL_END
61 |
--------------------------------------------------------------------------------
/src/CoreDataEnvir/ManagedObject/NSManagedObject_Background.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSManagedObject_Background.h
3 | // CoreDataEnvirSample
4 | //
5 | // Created by NicholasXu on 15/8/30.
6 | // Copyright (c) 2015年 Nicholas.Xu. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface NSManagedObject (CDEBackground)
15 |
16 | /**
17 | Creating managed object on main thread.
18 | */
19 | + (instancetype)insertItemOnBackground;
20 |
21 | /**
22 | Creating managed object in main context by filling 'block'
23 | */
24 | + (instancetype)insertItemOnBackgroundWithFillingBlock:(void(^)(NSManagedObject* item))fillingBlock;
25 |
26 | /**
27 | Just fetching record items by the predicate in main context.
28 | */
29 | + (NSArray *)itemsOnBackground;
30 |
31 | /**
32 | Fetch record items in main context by predicate.
33 | */
34 | + (NSArray *)itemsOnBackgroundWithPredicate:(NSPredicate *)predicate;
35 |
36 | /**
37 | Fetch record items in main context by formated string.
38 | */
39 | + (NSArray *)itemsOnBackgroundWithFormat:(NSString *)fmt,...;
40 |
41 | /**
42 | * Fetch record items in main context by predicate format string more simpler.
43 | *
44 | * @param sortDescriptions SortDescriptions
45 | * @param fmt Predicate format string.
46 | *
47 | * @return Array of items match the condition.
48 | */
49 | + (NSArray *)itemsOnBackgroundSortDescriptions:(NSArray *)sortDescriptions withFormat:(NSString *)fmt,...;
50 |
51 | /**
52 | * Fetch record items in main context by predicate format string more simpler.
53 | *
54 | * @param sortDescriptions SortDescriptions
55 | * @param offset offset
56 | * @param limitNumber limit number
57 | * @param fmt predicate format string.
58 | *
59 | * @return Array of items match the condition.
60 | */
61 | + (NSArray *)itemsOnBackgroundSortDescriptions:(NSArray *)sortDescriptions fromOffset:(NSUInteger)offset limitedBy:(NSUInteger)limitNumber withFormat:(NSString *)fmt,...;
62 |
63 | /**
64 | * Fetching last record item.
65 | */
66 | + (instancetype)lastItemOnBackground;
67 |
68 | /**
69 | * Fetch record item by predicate in main context.
70 | *
71 | * @param predicate Predicate object.s
72 | *
73 | * @return Last item of the managed object in context.
74 | */
75 | + (instancetype)lastItemOnBackgroundWithPredicate:(NSPredicate *)predicate;
76 |
77 | /**
78 |
79 | */
80 | /**
81 | * Fetch record item by formated string in main context.
82 | *
83 | * @param fmt Predicate format.
84 | *
85 | * @return Last item of the managed object in context.
86 | */
87 | + (instancetype)lastItemOnBackgroundWithFormat:(NSString *)fmt,...;
88 |
89 | @end
90 |
91 | NS_ASSUME_NONNULL_END
92 |
--------------------------------------------------------------------------------
/src/CoreDataEnvir/ManagedObject/NSManagedObject_Background.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSManagedObject_Background.m
3 | // CoreDataEnvirSample
4 | //
5 | // Created by NicholasXu on 15/8/30.
6 | // Copyright (c) 2015年 Nicholas.Xu. All rights reserved.
7 | //
8 |
9 | #import "NSManagedObject_Background.h"
10 | #import "CoreDataEnvir_Background.h"
11 | #import "CoreDataEnvir_Private.h"
12 | #import "NSManagedObject_Convenient.h"
13 |
14 | @implementation NSManagedObject (CDEBackground)
15 |
16 | /**
17 | * Insert an item.
18 | */
19 | + (instancetype)insertItemOnBackground
20 | {
21 | CoreDataEnvir *db = [CoreDataEnvir backgroundInstance];
22 | id item = nil;
23 | item = [self insertItemInContext:db];
24 | return item;
25 | }
26 |
27 | /**
28 | * Insert an item by block
29 | *
30 | * @param fillingBlock Fill data with this block
31 | *
32 | * @return NSManagedObject
33 | */
34 | + (instancetype)insertItemOnBackgroundWithFillingBlock:(void (^)(id item))fillingBlock
35 | {
36 | CoreDataEnvir* db = [CoreDataEnvir backgroundInstance];
37 | [db asyncWithBlock:^(CoreDataEnvir * _Nonnull db) {
38 | [self insertItemInContext:db fillData:fillingBlock];
39 | [db saveDataBase];
40 | }];
41 | return nil;
42 | }
43 |
44 | + (NSArray *)itemsOnBackground
45 | {
46 | CoreDataEnvir *db = [CoreDataEnvir backgroundInstance];
47 | NSArray *items = [db fetchItemsByEntityDescriptionName:NSStringFromClass(self)];
48 |
49 | return items;
50 | }
51 |
52 | + (NSArray *)itemsOnBackgroundWithPredicate:(NSPredicate *)predicate
53 | {
54 | CoreDataEnvir *db = [CoreDataEnvir backgroundInstance];
55 | NSArray *items = [db fetchItemsByEntityDescriptionName:NSStringFromClass(self) usingPredicate:predicate];
56 | return items;
57 | }
58 |
59 | + (NSArray *)itemsOnBackgroundWithFormat:(NSString *)fmt, ...
60 | {
61 | va_list args;
62 | va_start(args, fmt);
63 | NSPredicate *pred = [NSPredicate predicateWithFormat:fmt arguments:args];
64 | va_end(args);
65 | CoreDataEnvir *db = [CoreDataEnvir backgroundInstance];
66 | NSArray *items = [db fetchItemsByEntityDescriptionName:NSStringFromClass(self) usingPredicate:pred];
67 | return items;
68 | }
69 |
70 | + (NSArray *)itemsOnBackgroundSortDescriptions:(NSArray *)sortDescriptions withFormat:(NSString *)fmt, ...
71 | {
72 | va_list args;
73 | va_start(args, fmt);
74 | NSPredicate *pred = [NSPredicate predicateWithFormat:fmt arguments:args];
75 | va_end(args);
76 | CoreDataEnvir *db = [CoreDataEnvir backgroundInstance];
77 | NSArray *items = [db fetchItemsByEntityDescriptionName:NSStringFromClass(self) usingPredicate:pred usingSortDescriptions:sortDescriptions];
78 | return items;
79 | }
80 |
81 | + (NSArray *)itemsOnBackgroundSortDescriptions:(NSArray *)sortDescriptions fromOffset:(NSUInteger)offset limitedBy:(NSUInteger)limitNumber withFormat:(NSString *)fmt, ...
82 | {
83 | va_list args;
84 | va_start(args, fmt);
85 | NSPredicate *pred = [NSPredicate predicateWithFormat:fmt arguments:args];
86 | va_end(args);
87 | CoreDataEnvir *db = [CoreDataEnvir backgroundInstance];
88 | NSArray *items = [db fetchItemsByEntityDescriptionName:NSStringFromClass(self) usingPredicate:pred usingSortDescriptions:sortDescriptions fromOffset:offset LimitedBy:limitNumber];
89 | return items;
90 | }
91 |
92 | + (instancetype)lastItemOnBackground
93 | {
94 | return [[self itemsOnBackground] lastObject];
95 | }
96 |
97 | + (instancetype)lastItemOnBackgroundWithPredicate:(NSPredicate *)predicate
98 | {
99 | return [[self itemsInContext:[CoreDataEnvir backgroundInstance] usingPredicate:predicate] lastObject];
100 | }
101 |
102 | + (instancetype)lastItemOnBackgroundWithFormat:(NSString *)fmt, ...
103 | {
104 | va_list args;
105 | va_start(args, fmt);
106 | NSPredicate *pred = [NSPredicate predicateWithFormat:fmt arguments:args];
107 | va_end(args);
108 | return [self lastItemOnBackgroundWithPredicate:pred];
109 | }
110 |
111 | @end
112 |
--------------------------------------------------------------------------------
/src/CoreDataEnvir/ManagedObject/NSManagedObject_Convenient.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSManagedObject_Convient.h
3 | // CoreDataEnvirSample
4 | //
5 | // Created by NicholasXu on 15/8/30.
6 | // Copyright (c) 2015年 Nicholas.Xu. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface NSManagedObject (CDEConevient)
15 |
16 | + (NSUInteger)totalCountInContext:(CoreDataEnvir*)db forConfiguration:(NSString* _Nullable)name;
17 |
18 | #pragma mark - Inserting operations.
19 |
20 | + (NSFetchRequest*)newFetchRequestInContext:(CoreDataEnvir*)db;
21 |
22 | /**
23 | Creating managed object on background thread.
24 | */
25 | + (instancetype)insertItemInContext:(CoreDataEnvir *)cde;
26 |
27 | /**
28 | Createing managed object in specified context with filling 'block'
29 | */
30 | + (instancetype)insertItemInContext:(CoreDataEnvir *)cde fillData:(void (^)(NSManagedObject* item))fillingBlock;
31 |
32 | #pragma mark - Fetching operations.
33 |
34 | /**
35 | Fetching record items in specified context.
36 | */
37 | + (NSArray *)itemsInContext:(CoreDataEnvir *)cde;
38 |
39 | /**
40 | Fetch record items by predicate.
41 | */
42 | + (NSArray *)itemsInContext:(CoreDataEnvir *)cde usingPredicate:(NSPredicate *)predicate;
43 |
44 | /**
45 | Fetch record items by format string.
46 | */
47 | + (NSArray *)itemsInContext:(CoreDataEnvir *)cde withFormat:(NSString *)fmt,...;
48 |
49 | /**
50 | * Fetch items by sort descriptions.
51 | *
52 | * @param cde CoreDataEnvir instance.
53 | * @param sortDescriptions SortDescriptions
54 | * @param fmt Predicate format.
55 | *
56 | * @return Array of items match the condition.
57 | */
58 | + (NSArray *)itemsInContext:(CoreDataEnvir *)cde sortDescriptions:(NSArray *)sortDescriptions withFormat:(NSString *)fmt,...;
59 |
60 | /**
61 | * Fetch items addition by limited range.
62 | *
63 | * @param cde CoreDataEnvir instance
64 | * @param sortDescriptions SortDescriptions
65 | * @param offset offset
66 | * @param limitNumber limted number
67 | * @param fmt Predicate format.
68 | *
69 | * @return Array of items match the condition.
70 | */
71 | + (NSArray *)itemsInContext:(CoreDataEnvir *)cde sortDescriptions:(NSArray *)sortDescriptions fromOffset:(NSUInteger)offset limitedBy:(NSUInteger)limitNumber withFormat:(NSString *)fmt,...;
72 |
73 | /**
74 | * Fetch item in specified context.
75 | *
76 | * @param cde CoreDataEnvir instance
77 | *
78 | * @return Last item of the managed object in context.
79 | */
80 | + (instancetype)lastItemInContext:(CoreDataEnvir *)cde;
81 |
82 | /**
83 | * Fetch item in specified context through predicate.
84 | *
85 | * @param cde CoreDataEnvir instance
86 | * @param predicate Predicate.
87 | *
88 | * @return Last item of the managed object in context.
89 | */
90 | + (instancetype)lastItemInContext:(CoreDataEnvir *)cde usingPredicate:(NSPredicate *)predicate;
91 |
92 | /**
93 | * Fetch item in specified context through format string.
94 | *
95 | * @param cde CoreDataEnvir object.
96 | * @param fmt Predicate format string.
97 | *
98 | * @return Last item of the managed object in context.
99 | */
100 | + (instancetype)lastItemInContext:(CoreDataEnvir *)cde withFormat:(NSString *)fmt,...;
101 |
102 | #pragma mark - fault process.
103 |
104 | /**
105 | * Update NSManagedObject if faulted.
106 | *
107 | * @return Updated object.
108 | */
109 | - (instancetype)update;
110 |
111 | /**
112 | Update NSManagedObject in specified context if faulted.
113 |
114 | @param cde CoreDataEnvir object.
115 | */
116 | - (instancetype)updateInContext:(CoreDataEnvir *)cde;
117 |
118 | #pragma mark - Deleting .
119 |
120 | /**
121 | * Remove item.
122 | *
123 | * @param cde CoreDataEnvir object.
124 | */
125 | - (void)removeFrom:(CoreDataEnvir *)cde;
126 |
127 | /**
128 | * Remove item.
129 | */
130 | - (void)remove;
131 |
132 | #pragma mark - Drive to save.
133 |
134 | /**
135 | * Save db on main thread.
136 | *
137 | * @param cde CoreDataEnvir object.
138 | *
139 | * @return Success(YES) or failed(NO).
140 | */
141 | - (BOOL)saveTo:(CoreDataEnvir *)cde;
142 |
143 | /**
144 | Save db on main thread.
145 | */
146 | - (BOOL)save;
147 |
148 | /**
149 | * Save db on main thread.
150 | *
151 | * @param cde CoreDataEnvir object.
152 | *
153 | * @return Success(YES) or failed(NO).
154 | */
155 | - (BOOL)saveTo:(CoreDataEnvir *)cde forConfiguration:(NSString*)name;
156 |
157 | @end
158 |
159 | NS_ASSUME_NONNULL_END
160 |
--------------------------------------------------------------------------------
/src/CoreDataEnvir/ManagedObject/NSManagedObject_Convenient.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSManagedObject_Convient.m
3 | // CoreDataEnvirSample
4 | //
5 | // Created by NicholasXu on 15/8/30.
6 | // Copyright (c) 2015年 Nicholas.Xu. All rights reserved.
7 | //
8 |
9 | #import "NSManagedObject_Convenient.h"
10 | #import "CoreDataEnvir_Private.h"
11 | #import "CoreDataEnvir_Main.h"
12 | #import "CoreDataEnvir_Background.h"
13 |
14 | @implementation NSManagedObject (CDEConevient)
15 |
16 | + (NSUInteger)totalCountInContext:(CoreDataEnvir *)db forConfiguration:(NSString *)name {
17 | NSFetchRequest* req = [self newFetchRequestInContext:db];
18 | if (name.length) {
19 | NSPersistentStore* store = [db persistentStoreForConfiguration:name];
20 | req.affectedStores = @[store];
21 | }
22 | return [db countForFetchRequest:req error:nil];
23 | }
24 |
25 | + (NSFetchRequest*)newFetchRequestInContext:(CoreDataEnvir*)db {
26 | NSFetchRequest *req = [[NSFetchRequest alloc] init];
27 | NSString* name = NSStringFromClass(self.class);
28 | NSAssert(name.length, @"class name not found.");
29 | NSEntityDescription *entity = [NSEntityDescription entityForName:name inManagedObjectContext:db.context];
30 | [req setEntity:entity];
31 | return req;
32 | }
33 |
34 | #pragma mark - Insert item record
35 |
36 | + (instancetype)insertItemInContext:(CoreDataEnvir *)cde
37 | {
38 | id item = nil;
39 | NSError* err = nil;
40 | item = [cde buildManagedObjectByClass:self error:&err];
41 | return item;
42 | }
43 |
44 | + (instancetype)insertItemInContext:(CoreDataEnvir *)cde fillData:(void (^)(id item))fillingBlock
45 | {
46 | id item = [self insertItemInContext:cde];
47 | fillingBlock(item);
48 | return item;
49 | }
50 |
51 | #pragma mark - fetch items
52 |
53 | + (NSArray *)itemsInContext:(CoreDataEnvir *)cde
54 | {
55 | NSArray *items = [cde fetchItemsByEntityDescriptionName:NSStringFromClass(self)];
56 | return items;
57 | }
58 |
59 | + (NSArray *)itemsInContext:(CoreDataEnvir *)cde usingPredicate:(NSPredicate *)predicate
60 | {
61 | NSArray *items = [cde fetchItemsByEntityDescriptionName:NSStringFromClass(self) usingPredicate:predicate];
62 | return items;
63 | }
64 |
65 | + (NSArray *)itemsInContext:(CoreDataEnvir *)cde withFormat:(NSString *)fmt, ...
66 | {
67 | va_list args;
68 | va_start(args, fmt);
69 | NSPredicate *pred = [NSPredicate predicateWithFormat:fmt arguments:args];
70 | va_end(args);
71 |
72 | NSArray *items = [cde fetchItemsByEntityDescriptionName:NSStringFromClass(self) usingPredicate:pred];
73 | return items;
74 | }
75 |
76 | + (NSArray *)itemsInContext:(CoreDataEnvir *)cde sortDescriptions:(NSArray *)sortDescriptions withFormat:(NSString *)fmt, ...
77 | {
78 | va_list args;
79 | va_start(args, fmt);
80 | NSPredicate *pred = [NSPredicate predicateWithFormat:fmt arguments:args];
81 | va_end(args);
82 | NSArray *items = [cde fetchItemsByEntityDescriptionName:NSStringFromClass(self) usingPredicate:pred usingSortDescriptions:sortDescriptions];
83 | return items;
84 | }
85 |
86 | + (NSArray *)itemsInContext:(CoreDataEnvir *)cde sortDescriptions:(NSArray *)sortDescriptions fromOffset:(NSUInteger)offset limitedBy:(NSUInteger)limitNumber withFormat:(NSString *)fmt, ...
87 | {
88 | va_list args;
89 | va_start(args, fmt);
90 | NSPredicate *pred = [NSPredicate predicateWithFormat:fmt arguments:args];
91 | va_end(args);
92 | NSArray *items = [cde fetchItemsByEntityDescriptionName:NSStringFromClass(self) usingPredicate:pred usingSortDescriptions:sortDescriptions fromOffset:offset LimitedBy:limitNumber];
93 | return items;
94 | }
95 |
96 | #pragma mark - fetch last item
97 |
98 | + (instancetype)lastItemInContext:(CoreDataEnvir *)cde
99 | {
100 | return [[self itemsInContext:cde] lastObject];
101 | }
102 |
103 | + (instancetype)lastItemInContext:(CoreDataEnvir *)cde usingPredicate:(NSPredicate *)predicate
104 | {
105 | return [[self itemsInContext:cde usingPredicate:predicate] lastObject];
106 | }
107 |
108 | + (instancetype)lastItemInContext:(CoreDataEnvir *)cde withFormat:(NSString *)fmt, ...
109 | {
110 | va_list args;
111 | va_start(args, fmt);
112 | NSPredicate *pred = [NSPredicate predicateWithFormat:fmt arguments:args];
113 | va_end(args);
114 |
115 | return [[self itemsInContext:cde usingPredicate:pred] lastObject];
116 | }
117 |
118 | #pragma mark - merge context when update
119 |
120 | - (instancetype)update
121 | {
122 | if ([NSThread isMainThread]) {
123 | return [[CoreDataEnvir instance] updateDataItem:self];
124 | }
125 | return nil;
126 | }
127 |
128 | - (instancetype)updateInContext:(CoreDataEnvir *)cde
129 | {
130 | return [cde updateDataItem:self];
131 | }
132 |
133 | - (void)removeFrom:(CoreDataEnvir *)cde
134 | {
135 | if (!cde) {
136 | return;
137 | }
138 | [cde deleteDataItem:self];
139 | }
140 |
141 | - (void)remove
142 | {
143 | if (![NSThread isMainThread]) {
144 | #if DEBUG
145 | NSLog(@"Remove data failed, cannot run on non-main thread!");
146 | #endif
147 | [[NSException exceptionWithName:@"CoreDataEnviroment" reason:@"Remove data failed, must run on main thread!" userInfo:nil] raise];
148 | return;
149 | }
150 | if (![CoreDataEnvir mainInstance]) {
151 | return;
152 | }
153 | [[CoreDataEnvir mainInstance] deleteDataItem:self];
154 | }
155 |
156 | - (BOOL)saveTo:(CoreDataEnvir *)cde
157 | {
158 | if (!cde) {
159 | return NO;
160 | }
161 |
162 | return [cde saveDataBase];
163 | }
164 |
165 | - (BOOL)save
166 | {
167 | if (![NSThread isMainThread]) {
168 | #if DEBUG
169 | NSLog(@"Save data failed, cannot run on non-main thread!");
170 | #endif
171 | [[NSException exceptionWithName:@"CoreDataEnviroment" reason:@"Save data failed, must run on main thread!" userInfo:nil] raise];
172 | return NO;
173 | }
174 | if (![CoreDataEnvir mainInstance]) {
175 | return NO;
176 | }
177 |
178 | return [[CoreDataEnvir mainInstance] saveDataBase];
179 | }
180 |
181 | - (BOOL)saveTo:(CoreDataEnvir *)cde forConfiguration:(NSString *)name {
182 | NSPersistentStore* store = [cde persistentStoreForConfiguration:name];
183 | [cde.context assignObject:self toPersistentStore:store];
184 | [cde saveDataBase];
185 | return NO;
186 | }
187 |
188 | @end
189 |
--------------------------------------------------------------------------------
/src/CoreDataEnvir/ManagedObject/NSManagedObject_MainThread.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSManagedObject_MainThread.h
3 | // CoreDataEnvirSample
4 | //
5 | // Created by NicholasXu on 15/8/30.
6 | // Copyright (c) 2015年 Nicholas.Xu. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface NSManagedObject (CDEMainThread)
15 |
16 | #pragma mark - Inserting operations.
17 |
18 | /**
19 | Creating managed object on main thread.
20 | */
21 | + (instancetype)insertItem;
22 |
23 | /**
24 | Creating managed object in main context by filling 'block'
25 | */
26 | + (instancetype _Nullable)insertItemWithFillingBlock:(void(^)(NSManagedObject* _Nullable item))fillingBlock;
27 |
28 | + (NSUInteger)totalCount;
29 |
30 | /**
31 | Just fetching record items by the predicate in main context.
32 | */
33 | + (NSArray *)items;
34 |
35 | + (NSArray * _Nullable)itemsOffset:(NSUInteger)offset withLimit:(NSUInteger)limitNumber;
36 |
37 | /**
38 | Fetch record items in main context by predicate.
39 | */
40 | + (NSArray *)itemsWithPredicate:(NSPredicate *)predicate;
41 |
42 | /**
43 | Fetch record items in main context by formated string.
44 | */
45 | + (NSArray *)itemsWithFormat:(NSString *)fmt,...;
46 |
47 | /**
48 | * Fetch record items in main context by predicate format string more simpler.
49 | *
50 | * @param sortDescriptions SortDescriptions
51 | * @param fmt Predicate format string.
52 | *
53 | * @return Array of items match the condition.
54 | */
55 | + (NSArray *)itemsSortDescriptions:(NSArray *)sortDescriptions withFormat:(NSString *)fmt,...;
56 |
57 | /**
58 | * Fetch record items in main context by predicate format string more simpler.
59 | *
60 | * @param sortDescriptions SortDescriptions
61 | * @param offset offset
62 | * @param limitNumber limit number
63 | * @param fmt predicate format string.
64 | *
65 | * @return Array of items match the condition.
66 | */
67 | + (NSArray *)itemsSortDescriptions:(NSArray *)sortDescriptions fromOffset:(NSUInteger)offset limitedBy:(NSUInteger)limitNumber withFormat:(NSString *)fmt,...;
68 |
69 | + (NSArray *)itemsWithSortDescriptions:(NSArray * _Nullable)sortDescriptions fromOffset:(NSUInteger)offset limitedBy:(NSUInteger)limitNumber andPredicate:(NSPredicate* _Nullable)predicate;
70 |
71 | /**
72 | * Fetching last record item.
73 | */
74 | + (instancetype)lastItem;
75 |
76 | /**
77 | * Fetch record item by predicate in main context.
78 | *
79 | * @param predicate Predicate object.s
80 | *
81 | * @return Last item of the managed object in context.
82 | */
83 | + (instancetype)lastItemWithPredicate:(NSPredicate *)predicate;
84 |
85 | /**
86 |
87 | */
88 | /**
89 | * Fetch record item by formated string in main context.
90 | *
91 | * @param fmt Predicate format.
92 | *
93 | * @return Last item of the managed object in context.
94 | */
95 | + (instancetype)lastItemWithFormat:(NSString *)fmt,...;
96 |
97 | @end
98 |
99 | NS_ASSUME_NONNULL_END
100 |
--------------------------------------------------------------------------------
/src/CoreDataEnvir/ManagedObject/NSManagedObject_MainThread.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSManagedObject_MainThread.m
3 | // CoreDataEnvirSample
4 | //
5 | // Created by NicholasXu on 15/8/30.
6 | // Copyright (c) 2015年 Nicholas.Xu. All rights reserved.
7 | //
8 |
9 | #import "NSManagedObject_MainThread.h"
10 |
11 | #import "CoreDataEnvir_Main.h"
12 | #import "CoreDataEnvir_Private.h"
13 | #import "CoreDataEnvir.h"
14 | #import "NSManagedObject_Convenient.h"
15 |
16 | @implementation NSManagedObject (CDEMainThread)
17 |
18 |
19 | /**
20 | * Insert an item.
21 | *
22 | * @return NSManagedObject
23 | */
24 | + (instancetype)insertItem
25 | {
26 | if (![NSThread isMainThread]) {
27 | #if DEBUG
28 | NSLog(@"Insert item record failed, please run on main thread!");
29 | #endif
30 | [[NSException exceptionWithName:@"CoreDataEnviroment" reason:@"Insert item record failed, must run on main thread!" userInfo:nil] raise];
31 | return nil;
32 | }
33 | CoreDataEnvir *db = [CoreDataEnvir mainInstance];
34 | id item = [self insertItemInContext:db];
35 | return item;
36 | }
37 |
38 | /**
39 | * Insert an item by block
40 | *
41 | * @param fillingBlock Fill data
42 | *
43 | * @return NSManagedObject
44 | */
45 | + (instancetype)insertItemWithFillingBlock:(void (^)(id _Nullable item))fillingBlock
46 | {
47 | id item = [self insertItem];
48 | fillingBlock(item);
49 | return item;
50 | }
51 |
52 | + (NSUInteger)totalCount {
53 | if (![NSThread isMainThread]) {
54 | [[NSException exceptionWithName:@"CoreDataEnviroment" reason:@"Fetch all items record failed, must run on main thread!" userInfo:nil] raise];
55 | return NSUIntegerMax;
56 | }
57 |
58 | CoreDataEnvir *db = [CoreDataEnvir mainInstance];
59 | NSFetchRequest* req = [self newFetchRequestInContext:db];
60 | return [db countForFetchRequest:req error:nil];
61 | }
62 |
63 | + (NSArray *)items
64 | {
65 | if (![NSThread isMainThread]) {
66 | #if DEBUG
67 | NSLog(@"Fetch all items record failed, please run on main thread!");
68 | #endif
69 | [[NSException exceptionWithName:@"CoreDataEnviroment" reason:@"Fetch all items record failed, must run on main thread!" userInfo:nil] raise];
70 | return nil;
71 | }
72 | CoreDataEnvir *db = [CoreDataEnvir mainInstance];
73 | NSArray *items = [db fetchItemsByEntityDescriptionName:NSStringFromClass(self)];
74 |
75 | return items;
76 | }
77 |
78 | + (NSArray *)itemsOffset:(NSUInteger)offset withLimit:(NSUInteger)limitNumber {
79 | CoreDataEnvir *db = [CoreDataEnvir mainInstance];
80 |
81 | NSArray *items = [db fetchItemsByEntityDescriptionName:NSStringFromClass(self) usingPredicate:nil usingSortDescriptions:nil fromOffset:offset LimitedBy:limitNumber];
82 |
83 | return items;
84 | }
85 |
86 | + (NSArray *)itemsWithPredicate:(NSPredicate *)predicate
87 | {
88 | if (![NSThread isMainThread]) {
89 | #if DEBUG
90 | NSLog(@"Fetch item record failed, please run on main thread!");
91 | #endif
92 | [[NSException exceptionWithName:@"CoreDataEnviroment" reason:@"Fetch item record failed, must run on main thread!" userInfo:nil] raise];
93 | return nil;
94 | }
95 | CoreDataEnvir *db = [CoreDataEnvir mainInstance];
96 | NSArray *items = [db fetchItemsByEntityDescriptionName:NSStringFromClass(self) usingPredicate:predicate];
97 | return items;
98 | }
99 |
100 | + (NSArray *)itemsWithFormat:(NSString *)fmt, ...
101 | {
102 | if (![NSThread isMainThread]) {
103 | #if DEBUG
104 | NSLog(@"Fetch item record failed, please run on main thread!");
105 | #endif
106 | [[NSException exceptionWithName:@"CoreDataEnviroment" reason:@"Fetch item record failed, must run on main thread!" userInfo:nil] raise];
107 | return nil;
108 | }
109 |
110 | va_list args;
111 | va_start(args, fmt);
112 | NSPredicate *pred = [NSPredicate predicateWithFormat:fmt arguments:args];
113 | va_end(args);
114 | CoreDataEnvir *db = [CoreDataEnvir mainInstance];
115 | NSArray *items = [db fetchItemsByEntityDescriptionName:NSStringFromClass(self) usingPredicate:pred];
116 | return items;
117 | }
118 |
119 | + (NSArray *)itemsSortDescriptions:(NSArray *)sortDescriptions withFormat:(NSString *)fmt, ...
120 | {
121 | if (![NSThread isMainThread]) {
122 | #if DEBUG
123 | NSLog(@"Fetch item record failed, please run on main thread!");
124 | #endif
125 | [[NSException exceptionWithName:@"CoreDataEnviroment" reason:@"Fetch item record failed, must run on main thread!" userInfo:nil] raise];
126 | return nil;
127 | }
128 |
129 | va_list args;
130 | va_start(args, fmt);
131 | NSPredicate *pred = [NSPredicate predicateWithFormat:fmt arguments:args];
132 | va_end(args);
133 | CoreDataEnvir *db = [CoreDataEnvir mainInstance];
134 | NSArray *items = [db fetchItemsByEntityDescriptionName:NSStringFromClass(self) usingPredicate:pred usingSortDescriptions:sortDescriptions];
135 | return items;
136 | }
137 |
138 | + (NSArray *)itemsSortDescriptions:(NSArray *)sortDescriptions fromOffset:(NSUInteger)offset limitedBy:(NSUInteger)limitNumber withFormat:(NSString *)fmt, ...
139 | {
140 | if (![NSThread isMainThread]) {
141 | #if DEBUG
142 | NSLog(@"Fetch item record failed, please run on main thread!");
143 | #endif
144 | [[NSException exceptionWithName:@"CoreDataEnviroment" reason:@"Fetch item record failed, must run on main thread!" userInfo:nil] raise];
145 | return nil;
146 | }
147 |
148 | va_list args;
149 | va_start(args, fmt);
150 | NSPredicate *pred = [NSPredicate predicateWithFormat:fmt arguments:args];
151 | va_end(args);
152 | CoreDataEnvir *db = [CoreDataEnvir mainInstance];
153 | NSArray *items = [db fetchItemsByEntityDescriptionName:NSStringFromClass(self) usingPredicate:pred usingSortDescriptions:sortDescriptions fromOffset:offset LimitedBy:limitNumber];
154 | return items;
155 | }
156 |
157 | + (NSArray *)itemsWithSortDescriptions:(NSArray *)sortDescriptions fromOffset:(NSUInteger)offset limitedBy:(NSUInteger)limitNumber andPredicate:(NSPredicate *)predicate {
158 | CoreDataEnvir *db = [CoreDataEnvir mainInstance];
159 | NSArray* items = [db fetchItemsByEntityDescriptionName:NSStringFromClass(self) usingPredicate:predicate usingSortDescriptions:sortDescriptions fromOffset:offset LimitedBy:limitNumber];
160 | return items;
161 | }
162 |
163 | + (instancetype)lastItem
164 | {
165 | if (![NSThread isMainThread]) {
166 | #if DEBUG
167 | NSLog(@"Fetch last item record failed, please run on main thread!");
168 | #endif
169 | [[NSException exceptionWithName:@"CoreDataEnviroment" reason:@"Fetch last item record failed, must run on main thread!" userInfo:nil] raise];
170 | return nil;
171 | }
172 |
173 | return [[self items] lastObject];
174 | }
175 |
176 | + (instancetype)lastItemWithPredicate:(NSPredicate *)predicate
177 | {
178 | if (![NSThread isMainThread]) {
179 | #if DEBUG
180 | NSLog(@"Fetch last item record failed, please run on main thread!");
181 | #endif
182 | [[NSException exceptionWithName:@"CoreDataEnviroment" reason:@"Fetch last item record failed, must run on main thread!" userInfo:nil] raise];
183 | return nil;
184 | }
185 |
186 | return [[self itemsInContext:[CoreDataEnvir mainInstance] usingPredicate:predicate] lastObject];
187 | }
188 |
189 | + (instancetype)lastItemWithFormat:(NSString *)fmt, ...
190 | {
191 | va_list args;
192 | va_start(args, fmt);
193 | NSPredicate *pred = [NSPredicate predicateWithFormat:fmt arguments:args];
194 | va_end(args);
195 | return [self lastItemWithPredicate:pred];
196 | }
197 |
198 | @end
199 |
--------------------------------------------------------------------------------
/src/CoreDataEnvir/Private/CoreDataEnvir_Private.h:
--------------------------------------------------------------------------------
1 | //
2 | // CoreDataEnvir_Private.h
3 | // CoreDataEnvirSample
4 | //
5 | // Created by NicholasXu on 15/8/30.
6 | // Copyright (c) 2015年 Nicholas.Xu. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | extern id _Nullable _rescureDelegate;
15 | extern CoreDataEnvir* _Nullable _backgroundInstance;
16 | extern CoreDataEnvir* _Nullable _mainInstance;
17 | extern long _create_counter;
18 |
19 | @interface CoreDataEnvir (CDEPrivate)
20 |
21 | /**
22 | Rename database file with new registed name.
23 | */
24 | + (void)_renameDatabaseFile;
25 |
26 | - (NSDictionary*)defaultPersistentOptions;
27 |
28 | - (NSFetchRequest * _Nullable)newFetchRequestWithName:(NSString* _Nullable)name error:(NSError* _Nullable * _Nullable)error;
29 |
30 | - (NSFetchRequest * _Nullable)newFetchRequestWithClass:(Class _Nullable)clazz error:(NSError * _Nullable * _Nullable)error;
31 |
32 | /**
33 | Insert a new record into the table by className.
34 | */
35 | - (NSManagedObject * _Nullable)buildManagedObjectByName:(NSString * _Nonnull)className error:(NSError**)error;
36 |
37 | /// Insert a new record into the table by Class type.
38 | /// @param theClass Object class
39 | /// @param error NSError with failed information.
40 | - (NSManagedObject* _Nullable)buildManagedObjectByClass:(Class _Nonnull)theClass error:(NSError* _Nullable * _Nullable)error;
41 |
42 | /// Create entity from a 'Class' object
43 | /// @param clazz Class object
44 | - (NSEntityDescription * _Nullable) entityDescriptionByClass:(Class _Nullable)clazz;
45 |
46 | /**
47 | Get entity descritpion from name string
48 | */
49 | - (NSEntityDescription * _Nullable) entityDescriptionByName:(NSString *_Nullable)className;
50 |
51 | - (NSUInteger)countForFetchRequest:(NSFetchRequest* _Nonnull)fetchRequest error:(NSError* _Nullable * _Nullable)error;
52 |
53 | /**
54 | Fetching record item.
55 | */
56 | - (NSArray *)fetchItemsByEntityDescriptionName:(NSString *)entityName;
57 | - (NSArray *)fetchItemsByEntityDescriptionName:(NSString *)entityName usingPredicate:(NSPredicate *) predicate;
58 | - (NSArray *)fetchItemsByEntityDescriptionName:(NSString *)entityName usingPredicate:(NSPredicate *)predicate usingSortDescriptions:(NSArray *)sortDescriptions;
59 | - (NSArray *)fetchItemsByEntityDescriptionName:(NSString *)entityName usingPredicate:(NSPredicate * _Nullable) predicate usingSortDescriptions:(NSArray * _Nullable)sortDescriptions fromOffset:(NSUInteger) aOffset LimitedBy:(NSUInteger)aLimited;
60 |
61 | /**
62 | * Update context while data changes.
63 | *
64 | * @param notification NSNotification object.
65 | */
66 | - (void)updateContext:(NSNotification *)notification;
67 |
68 | /**
69 | * Merge context data while other context occur data changing.
70 | *
71 | * @param notification NSNotification object.
72 | */
73 | - (void)mergeChanges:(NSNotification *)notification;
74 |
75 | /**
76 | Send processPendingChanges message on non-main thread.
77 | You should call this method after cluster of actions.
78 | */
79 | - (void)sendPendingChanges;
80 |
81 |
82 |
83 | @end
84 |
85 | NS_ASSUME_NONNULL_END
86 |
--------------------------------------------------------------------------------
/src/CoreDataEnvir/Private/CoreDataEnvir_Private.m:
--------------------------------------------------------------------------------
1 | //
2 | // CoreDataEnvir_Private.m
3 | // CoreDataEnvirSample
4 | //
5 | // Created by NicholasXu on 15/8/30.
6 | // Copyright (c) 2015年 Nicholas.Xu. All rights reserved.
7 | //
8 |
9 | #import "CoreDataEnvir_Private.h"
10 |
11 | #import "CoreDataEnvir_Main.h"
12 |
13 | id _rescureDelegate;
14 | CoreDataEnvir *_backgroundInstance = nil;
15 | CoreDataEnvir *_mainInstance = nil;
16 | long _create_counter = 0;
17 |
18 | @implementation CoreDataEnvir (CDEPrivate)
19 |
20 | - (NSDictionary *)defaultPersistentOptions {
21 | NSDictionary *options = @{
22 | NSMigratePersistentStoresAutomaticallyOption:@YES, NSInferMappingModelAutomaticallyOption:@YES
23 | };
24 | return options;
25 | }
26 |
27 | - (NSFetchRequest *)newFetchRequestWithName:(NSString *)name error:(NSError **)error {
28 | NSEntityDescription *entity = [NSEntityDescription entityForName:name inManagedObjectContext:self.context];
29 | if (!entity) {
30 | *error = [NSError errorWithDomain:@"CoreDataEnvir: entity create failed" code:0 userInfo:nil];
31 | return nil;
32 | }
33 | NSFetchRequest *req = [[NSFetchRequest alloc] init];
34 | [req setEntity:entity];
35 | return req;
36 | }
37 |
38 | - (NSFetchRequest *)newFetchRequestWithClass:(Class)clazz error:(NSError **)error {
39 | if (!clazz) {
40 | *error = [NSError errorWithDomain:@"CoreDataEnvir: class is nil." code:0 userInfo:nil];
41 | return nil;
42 | }
43 | NSString* name = NSStringFromClass(clazz);
44 | NSFetchRequest *req = [self newFetchRequestWithName:name error:error];
45 | return req;
46 | }
47 |
48 | - (NSManagedObject *) buildManagedObjectByName:(NSString *)className error:(NSError *__autoreleasing _Nullable * _Nullable)error
49 | {
50 | NSManagedObject *_object = nil;
51 | _object = [NSEntityDescription insertNewObjectForEntityForName:className inManagedObjectContext:self.context];
52 | if (!_object) {
53 | NSString* msg = [NSString stringWithFormat:@"Error(%@): Insert object of class:(%@) failed", CDE_DOMAIN, className];
54 | if (*error) {
55 | *error = [NSError errorWithDomain:msg code:0 userInfo:nil];
56 | }
57 | NSAssert(false, msg);
58 | return nil;
59 | }
60 |
61 | return _object;
62 | }
63 |
64 | - (NSManagedObject *)buildManagedObjectByClass:(Class)theClass error:(NSError **)error {
65 | NSManagedObject *_object = nil;
66 | NSString* className = NSStringFromClass(theClass);
67 | if (!className) {
68 | NSString* msg = [NSString stringWithFormat:@"Error(%@): class: \"%@\" name not found.", CDE_DOMAIN, className];
69 | if (*error) {
70 | *error = [NSError errorWithDomain:msg code:0 userInfo:0];
71 | }
72 | NSAssert(false, msg);
73 | return nil;
74 | }
75 |
76 | _object = [self buildManagedObjectByName:className error:error];
77 | return _object;
78 | }
79 |
80 | - (NSEntityDescription *)entityDescriptionByClass:(Class)clazz {
81 | NSString* name = NSStringFromClass(clazz);
82 | return [self entityDescriptionByName:name];
83 | }
84 |
85 | - (NSEntityDescription *) entityDescriptionByName:(NSString *)className
86 | {
87 | return [NSEntityDescription entityForName:className inManagedObjectContext:self.context];
88 | }
89 |
90 | - (NSUInteger)countForFetchRequest:(NSFetchRequest *)fetchRequest error:(NSError **)error {
91 | return [self.context countForFetchRequest:fetchRequest error:error];
92 | }
93 |
94 | - (NSArray *) fetchItemsByEntityDescriptionName:(NSString *)entityName
95 | {
96 | NSArray *items = nil;
97 |
98 | NSEntityDescription* entity = [self entityDescriptionByName:entityName];
99 | if (!entity) {
100 | return nil;
101 | }
102 |
103 | NSFetchRequest *req = [[NSFetchRequest alloc] init];
104 | [req setEntity:entity];
105 |
106 | NSError *error = nil;
107 | items = [self.context executeFetchRequest:req error:&error];
108 | if (error) {
109 | NSLog(@"%s, error:%@, entityName:%@", __FUNCTION__, error, entityName);
110 | }
111 |
112 | return items;
113 | }
114 |
115 | - (NSArray *) fetchItemsByEntityDescriptionName:(NSString *)entityName usingPredicate:(NSPredicate *)predicate
116 | {
117 | NSArray *items = nil;
118 |
119 | NSFetchRequest *req = [[NSFetchRequest alloc] init];
120 | [req setEntity:[self entityDescriptionByName:entityName]];
121 | [req setPredicate:predicate];
122 |
123 | NSError *error = nil;
124 | items = [self.context executeFetchRequest:req error:&error];
125 | if (error) {
126 | NSLog(@"%s, error:%@, entityName:%@", __FUNCTION__, [error localizedDescription], entityName);
127 | }
128 |
129 | return items;
130 | }
131 |
132 | - (NSArray *) fetchItemsByEntityDescriptionName:(NSString *)entityName usingPredicate:(NSPredicate *)predicate usingSortDescriptions:(NSArray *)sortDescriptions
133 | {
134 | NSArray *items = nil;
135 |
136 | NSFetchRequest *req = [[NSFetchRequest alloc] init];
137 | NSEntityDescription * entityDescritpion = [self entityDescriptionByName:entityName];
138 | [req setEntity:entityDescritpion];
139 | [req setSortDescriptors:sortDescriptions];
140 | [req setPredicate:predicate];
141 | NSError *error = nil;
142 | items = [self.context executeFetchRequest:req error:&error];
143 | if (error) {
144 | NSLog(@"%s, error:%@", __FUNCTION__, [error localizedDescription]);
145 | }
146 |
147 | return items;
148 | }
149 |
150 | - (NSArray *) fetchItemsByEntityDescriptionName:(NSString *)entityName usingPredicate:(NSPredicate *)predicate usingSortDescriptions:(NSArray *)sortDescriptions fromOffset:(NSUInteger)aOffset LimitedBy:(NSUInteger)aLimited
151 | {
152 | NSArray *items = nil;
153 |
154 | NSFetchRequest *req = [[NSFetchRequest alloc] init];
155 | NSEntityDescription * entityDescritpion = [self entityDescriptionByName:entityName];
156 | [req setEntity:entityDescritpion];
157 | [req setSortDescriptors:sortDescriptions];
158 | [req setPredicate:predicate];
159 | [req setFetchOffset:aOffset];
160 | [req setFetchLimit:aLimited];
161 |
162 | NSError *error = nil;
163 |
164 | items = [self.context executeFetchRequest:req error:&error];
165 |
166 | if (error) {
167 | NSLog(@"%s, error:%@", __FUNCTION__, [error localizedDescription]);
168 | }
169 |
170 | return items;
171 | }
172 |
173 | - (void)updateContext:(NSNotification *)notification
174 | {
175 | #if DEBUG && CORE_DATA_ENVIR_SHOW_LOG
176 | NSLog(@"%s %@ ->>> %@", __FUNCTION__, notification.object, self.context);
177 | #endif
178 |
179 | void (^doWork)(void) = ^ {
180 | @try {
181 | //After this merge operating, context update it's state 'hasChanges' .
182 | [self.context mergeChangesFromContextDidSaveNotification:notification];
183 | }
184 | @catch (NSException *exception) {
185 | NSLog(@"exce :%@", exception);
186 | }
187 | @finally {
188 | //NSLog(@"Merge finished!");
189 | }
190 | };
191 | #pragma clang push
192 | #pragma clang diagnostic ignored "-Wdeprecated-declarations"
193 | if ([[UIDevice currentDevice] systemVersion].floatValue >= 8.0) {
194 | [self.persistentStoreCoordinator performBlockAndWait:doWork];
195 | }else {
196 | [self.persistentStoreCoordinator lock];
197 | doWork();
198 | [self.persistentStoreCoordinator unlock];
199 | }
200 | #pragma clang pop
201 |
202 | }
203 |
204 | /**
205 |
206 | this is called via observing "NSManagedObjectContextDidSaveNotification" from our ParseOperation
207 |
208 | */
209 | - (void)mergeChanges:(NSNotification *)notification {
210 | #if DEBUG && CORE_DATA_ENVIR_SHOW_LOG
211 | NSLog(@"%s [%@/%@] %@", __FUNCTION__, self.context, notification.object, [self currentDispatchQueueLabel]);
212 | #endif
213 |
214 | if (notification.object == self.context) {
215 | // main context save, no need to perform the merge
216 | return;
217 | }
218 |
219 | //[self performSelectorOnMainThread:@selector(updateContext:) withObject:notification waitUntilDone:NO];
220 | //Note:waitUntilDone:YES will cause method 'saveDatabase' and 'updateContext' fall in dead lock by '[storeCoordinator lock]'
221 | [self performSelector:@selector(updateContext:) onThread:[NSThread currentThread] withObject:notification waitUntilDone:YES];
222 | }
223 |
224 | - (void)sendPendingChanges
225 | {
226 | if ([NSThread isMainThread] ||
227 | !self.context) {
228 | return;
229 | }
230 | [self.context processPendingChanges];
231 | }
232 |
233 |
234 | @end
235 |
--------------------------------------------------------------------------------
/syncgit:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | git push origin --all
4 |
--------------------------------------------------------------------------------