From 6fbdd1014e0a1611bf60bd637fbea7e0a3c17b24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Quentin=20Mathe=CC=81?= Date: Mon, 18 Jan 2021 16:32:25 +0100 Subject: [PATCH 1/9] Add generics and nullability annotations to item graph --- StorageDataModel/COItemGraph.h | 32 ++++++++++++++++++-------------- StorageDataModel/COItemGraph.m | 1 + 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/StorageDataModel/COItemGraph.h b/StorageDataModel/COItemGraph.h index 883203b1d..b1ce6897b 100644 --- a/StorageDataModel/COItemGraph.h +++ b/StorageDataModel/COItemGraph.h @@ -10,6 +10,8 @@ @class ETUUID; @class COItem, COMutableItem; +NS_ASSUME_NONNULL_BEGIN + /** * @group Storage Data Model * @abstract @@ -28,21 +30,21 @@ /** * Returns the entry point UUID. */ -@property (nonatomic, readonly) ETUUID *rootItemUUID; +@property (nonatomic, readonly, nullable) ETUUID *rootItemUUID; /** * Returns an immutable item for the UUID. */ -- (COItem *)itemForUUID: (ETUUID *)aUUID; +- (nullable COItem *)itemForUUID: (ETUUID *)aUUID; /** * Returns all the item UUIDs in the graph, including -rootItemUUID. */ -@property (nonatomic, readonly) NSArray *itemUUIDs; +@property (nonatomic, readonly) NSArray *itemUUIDs; /** * Returns all the items in the graph. * * The returned item count is the same than -itemUUIDs. */ -@property (nonatomic, readonly) NSArray *items; +@property (nonatomic, readonly) NSArray *items; /** * Inserts the items in the graph, or updates existing items when the graph * contains items with matching UUIDs. @@ -51,7 +53,7 @@ * * May broadcast a change notification, up to the subclass. */ -- (void)insertOrUpdateItems: (NSArray *)items; +- (void)insertOrUpdateItems: (NSArray *)items; @end @@ -77,16 +79,16 @@ /** @taskunit Initialization */ -+ (COItemGraph *)itemGraphWithItemsRootFirst: (NSArray *)items; ++ (COItemGraph *)itemGraphWithItemsRootFirst: (NSArray *)items; /** * N.B. items doesn't need to contain rootItemUUID. */ -- (instancetype)initWithItemForUUID: (NSDictionary *)itemForUUID - rootItemUUID: (ETUUID *)root NS_DESIGNATED_INITIALIZER; +- (instancetype)initWithItemForUUID: (NSDictionary *)itemForUUID + rootItemUUID: (nullable ETUUID *)root NS_DESIGNATED_INITIALIZER; /** * N.B. items doesn't need to contain rootItemUUID. */ -- (instancetype)initWithItems: (NSArray *)items +- (instancetype)initWithItems: (NSArray *)items rootItemUUID: (ETUUID *)root; - (instancetype)initWithItemGraph: (id )aGraph; @@ -97,7 +99,7 @@ /** * See -[COItemGraph rootItemUUID]. */ -@property (nonatomic, strong) ETUUID *rootItemUUID; +@property (nonatomic, strong, nullable) ETUUID *rootItemUUID; /** * See -[COItemGraph itemForUUID:]. */ @@ -105,17 +107,17 @@ /** * See -[COItemGraph itemUUIDs]. */ -@property (nonatomic, readonly) NSArray *itemUUIDs; +@property (nonatomic, readonly) NSArray *itemUUIDs; /** * Returns all the items in the graph. * * The returned item count is the same than -itemUUIDs. */ -@property (nonatomic, readonly) NSArray *items; +@property (nonatomic, readonly) NSArray *items; /** * See -[COItemGraph insertOrUpdateItems:]. */ -- (void)insertOrUpdateItems: (NSArray *)items; +- (void)insertOrUpdateItems: (NSArray *)items; /** * Adds the items from the given item graph to the receiver. * @@ -149,4 +151,6 @@ BOOL COItemGraphEqualToItemGraph(id first, id second /** * If aGraph.rootItemUUID is nil, returns the empty set. */ -NSSet *COItemGraphReachableUUIDs(id aGraph); +NSSet *COItemGraphReachableUUIDs(id aGraph); + +NS_ASSUME_NONNULL_END diff --git a/StorageDataModel/COItemGraph.m b/StorageDataModel/COItemGraph.m index d3e2d1825..d6b1fa333 100644 --- a/StorageDataModel/COItemGraph.m +++ b/StorageDataModel/COItemGraph.m @@ -8,6 +8,7 @@ #import "COItemGraph.h" #import #import +#import #import "COItem.h" #import "COItem+JSON.h" #import "COItem+Binary.h" From a81f3be6f6d2331145e42ac5891a6b84853291ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Quentin=20Mathe=CC=81?= Date: Mon, 18 Jan 2021 16:59:47 +0100 Subject: [PATCH 2/9] Fix compilation by using libc++ instead of the default compiler stdlib --- CoreObject.xcodeproj/project.pbxproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CoreObject.xcodeproj/project.pbxproj b/CoreObject.xcodeproj/project.pbxproj index b3b08988e..96f2a4e09 100644 --- a/CoreObject.xcodeproj/project.pbxproj +++ b/CoreObject.xcodeproj/project.pbxproj @@ -4248,6 +4248,7 @@ C01FCF4F08A954540054247B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; @@ -4279,6 +4280,7 @@ C01FCF5008A954540054247B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; From 0ce942c8177b3f2371cd0363d11b1ace312b2f4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Quentin=20Mathe=CC=81?= Date: Mon, 25 Oct 2021 16:31:12 +0200 Subject: [PATCH 3/9] More generics related annotations --- Model/COLibrary.m | 2 +- Store/COSQLiteStore.h | 6 +++--- Store/COStoreTransaction.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Model/COLibrary.m b/Model/COLibrary.m index d3ab45aec..5c131457f 100644 --- a/Model/COLibrary.m +++ b/Model/COLibrary.m @@ -87,7 +87,7 @@ - (COSmartGroup *)libraryGroup COSmartGroup *group = [[COSmartGroup alloc] initWithObjectGraphContext: _internalTransientObjectGraphContext]; [group setName: _(@"All Objects")]; - group.targetCollection = [[[self.persistentRoots mappedCollection] rootObject] allObjects]; + group.targetCollection = [(id)[[self.persistentRoots mappedCollection] rootObject] allObjects]; #ifdef GNUSTEP group.predicate = [NSPredicate predicateWithFormat: @"isLibrary == YES"]; #else diff --git a/Store/COSQLiteStore.h b/Store/COSQLiteStore.h index 6698e0aa6..7aacbc23a 100644 --- a/Store/COSQLiteStore.h +++ b/Store/COSQLiteStore.h @@ -390,7 +390,7 @@ extern NSString *const COPersistentRootAttributeUsedSize; * * NOTE: Unstable API */ -- (NSArray *)revisionInfosForBackingStoreOfPersistentRootUUID: (ETUUID *)aPersistentRoot; +- (NSArray *)revisionInfosForBackingStoreOfPersistentRootUUID: (ETUUID *)aPersistentRoot; /** * Returns a delta between the given revision IDs. * The delta is uses the granularity of single inner objects, but not individual properties. @@ -420,8 +420,8 @@ extern NSString *const COPersistentRootAttributeUsedSize; /** * Only returns non-deleted persistent root UUIDs. */ -@property (nonatomic, readonly) NSArray *persistentRootUUIDs; -@property (nonatomic, readonly) NSArray *deletedPersistentRootUUIDs; +@property (nonatomic, readonly) NSArray *persistentRootUUIDs; +@property (nonatomic, readonly) NSArray *deletedPersistentRootUUIDs; /** * @return a snapshot of the state of a persistent root, or nil if diff --git a/Store/COStoreTransaction.h b/Store/COStoreTransaction.h index c0fb6e014..6de481210 100644 --- a/Store/COStoreTransaction.h +++ b/Store/COStoreTransaction.h @@ -30,7 +30,7 @@ /** @taskunit Transaction ID */ -@property (nonatomic, readonly) NSArray *persistentRootUUIDs; +@property (nonatomic, readonly) NSArray *persistentRootUUIDs; /** * Returns YES if this transaction contains an action affecting the mutable From b01e6a7dd0581e81288ad0334597ab520c6ffc5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Quentin=20Mathe=CC=81?= Date: Fri, 29 Oct 2021 14:34:29 +0200 Subject: [PATCH 4/9] Update Xcode project, bump deployment targets and fix warnings on macOS 10.9 and higher --- ...CrossPersistentRootDeadRelationshipCache.m | 12 ++--- Core/COPrimitiveCollection.m | 24 +++++----- CoreObject.xcodeproj/project.pbxproj | 44 ++++++++++++++----- Debugging/COSQLiteStore+Graphviz.m | 2 +- Store/COSQLiteStore.m | 4 +- Undo/COUndoTrackStore.m | 4 +- 6 files changed, 53 insertions(+), 37 deletions(-) diff --git a/Core/COCrossPersistentRootDeadRelationshipCache.m b/Core/COCrossPersistentRootDeadRelationshipCache.m index 1cdcf6c32..4e248b57d 100644 --- a/Core/COCrossPersistentRootDeadRelationshipCache.m +++ b/Core/COCrossPersistentRootDeadRelationshipCache.m @@ -16,10 +16,10 @@ - (instancetype)init { SUPERINIT; _pathToReferringObjects = [NSMutableDictionary new]; -#if TARGET_OS_IPHONE - _referringObjectToPaths = [NSMapTable weakToStrongObjectsMapTable]; -#else +#if GNUSTEP _referringObjectToPaths = [NSMapTable mapTableWithWeakToStrongObjects]; +#else + _referringObjectToPaths = [NSMapTable weakToStrongObjectsMapTable]; #endif return self; } @@ -35,10 +35,10 @@ - (void)addReferringObject: (COObject *)aReferrer // FIXME: If we don't ditch 10.7 support, we need a reverse mapping // from each referringObject to a path set, that can be used to remove // the referring objects when their object graph context is discarded. -#if TARGET_OS_IPHONE - referringObjects = [NSHashTable weakObjectsHashTable]; -#else +#ifdef GNUSTEP referringObjects = [NSHashTable hashTableWithWeakObjects]; +#else + referringObjects = [NSHashTable weakObjectsHashTable]; #endif _pathToReferringObjects[aPath] = referringObjects; diff --git a/Core/COPrimitiveCollection.m b/Core/COPrimitiveCollection.m index ff5c77798..801422afd 100644 --- a/Core/COPrimitiveCollection.m +++ b/Core/COPrimitiveCollection.m @@ -83,10 +83,10 @@ - (BOOL)isMutable - (NSPointerArray *)makeBacking { -#if TARGET_OS_IPHONE - return [NSPointerArray strongObjectsPointerArray]; -#else +#ifdef GNUSTEP return [NSPointerArray pointerArrayWithStrongObjects]; +#else + return [NSPointerArray strongObjectsPointerArray]; #endif } @@ -366,19 +366,19 @@ @implementation COUnsafeRetainedMutableArray - (NSPointerArray *)makeBacking { -#if TARGET_OS_IPHONE - return [NSPointerArray weakObjectsPointerArray]; -#else +#ifdef GNUSTEP return [NSPointerArray pointerArrayWithWeakObjects]; +#else + return [NSPointerArray weakObjectsPointerArray]; #endif } - (NSHashTable *)makeBackingHashTable { -#if TARGET_OS_IPHONE - return [NSHashTable weakObjectsHashTable]; -#else +#ifdef GNUSTEP return [NSHashTable hashTableWithWeakObjects]; +#else + return [NSHashTable weakObjectsHashTable]; #endif } @@ -672,10 +672,10 @@ @implementation COUnsafeRetainedMutableSet - (NSHashTable *)makeBacking { -#if TARGET_OS_IPHONE - return [NSHashTable weakObjectsHashTable]; -#else +#ifdef GNUSTEP return [NSHashTable hashTableWithWeakObjects]; +#else + return [NSHashTable weakObjectsHashTable]; #endif } diff --git a/CoreObject.xcodeproj/project.pbxproj b/CoreObject.xcodeproj/project.pbxproj index 96f2a4e09..400b1a39c 100644 --- a/CoreObject.xcodeproj/project.pbxproj +++ b/CoreObject.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 50; objects = { /* Begin PBXBuildFile section */ @@ -2970,7 +2970,7 @@ }; }; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "CoreObject" */; - compatibilityVersion = "Xcode 3.2"; + compatibilityVersion = "Xcode 9.3"; developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( @@ -3850,7 +3850,10 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = "iOS/TestCoreObject-Info.plist"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(SDKROOT)/usr/lib/system", @@ -3883,7 +3886,10 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = "iOS/TestCoreObject-Info.plist"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(SDKROOT)/usr/lib/system", @@ -3921,7 +3927,10 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = "TestCoreObject (iOS) copy2-Info.plist"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(SDKROOT)/usr/lib/system", @@ -3954,7 +3963,10 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = "TestCoreObject (iOS) copy2-Info.plist"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(SDKROOT)/usr/lib/system", @@ -4099,7 +4111,10 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = "iOS/TestCoreObject-Info.plist"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(SDKROOT)/usr/lib/system", @@ -4132,7 +4147,10 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = "iOS/TestCoreObject-Info.plist"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(SDKROOT)/usr/lib/system", @@ -4248,6 +4266,7 @@ C01FCF4F08A954540054247B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; @@ -4264,8 +4283,8 @@ GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_WARN_64_TO_32_BIT_CONVERSION = NO; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; - MACOSX_DEPLOYMENT_TARGET = 10.7; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MACOSX_DEPLOYMENT_TARGET = 10.9; ONLY_ACTIVE_ARCH = YES; OTHER_CFLAGS = "-DDEBUG"; SDKROOT = macosx; @@ -4280,6 +4299,7 @@ C01FCF5008A954540054247B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; @@ -4291,8 +4311,8 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = NO; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; - MACOSX_DEPLOYMENT_TARGET = 10.7; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MACOSX_DEPLOYMENT_TARGET = 10.9; SDKROOT = macosx; WARNING_CFLAGS = ( "-Wall", diff --git a/Debugging/COSQLiteStore+Graphviz.m b/Debugging/COSQLiteStore+Graphviz.m index f668ca89f..9d43ec196 100644 --- a/Debugging/COSQLiteStore+Graphviz.m +++ b/Debugging/COSQLiteStore+Graphviz.m @@ -82,7 +82,7 @@ - (NSString *)dotGraphForPersistentRootUUID: (ETUUID *)aPersistentRoot COPersistentRootInfo *info = [self persistentRootInfoForUUID: aPersistentRoot]; - assert(dispatch_get_current_queue() != queue_); + assert(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL) != dispatch_queue_get_label(queue_)); dispatch_sync(queue_, ^() { diff --git a/Store/COSQLiteStore.m b/Store/COSQLiteStore.m index 9cda29d02..84f387dc7 100644 --- a/Store/COSQLiteStore.m +++ b/Store/COSQLiteStore.m @@ -125,9 +125,7 @@ - (void)dealloc db_ = nil; }); -#if !(TARGET_OS_IPHONE) - // N.B.: We are using deployment target 10.7, so ARC does not manage libdispatch objects. - // If we switch to deployment target 10.8, ARC will manage libdispatch objects automatically. +#ifdef GNUSTEP // For GNUstep, ARC doesn't manage libdispatch objects since libobjc2 doesn't support it // currently (we compile CoreObject with -DOS_OBJECT_USE_OBJC=0). dispatch_release(queue_); diff --git a/Undo/COUndoTrackStore.m b/Undo/COUndoTrackStore.m index 7303a0361..7fec1fcd9 100644 --- a/Undo/COUndoTrackStore.m +++ b/Undo/COUndoTrackStore.m @@ -204,9 +204,7 @@ - (void)dealloc [_db close]; }); -#if !(TARGET_OS_IPHONE) - // N.B.: We are using deployment target 10.7, so ARC does not manage libdispatch objects. - // If we switch to deployment target 10.8, ARC will manage libdispatch objects automatically. +#ifdef GNUSTEP // For GNUstep, ARC doesn't manage libdispatch objects since libobjc2 doesn't support it // currently (we compile CoreObject with -DOS_OBJECT_USE_OBJC=0). dispatch_release(_queue); From fb6d1f1e6337ea433abfe922db1188cca2c5d143 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Quentin=20Mathe=CC=81?= Date: Fri, 29 Oct 2021 14:51:25 +0200 Subject: [PATCH 5/9] Fix test failure on recent macOS versions --- Extras/ValueTransformers/COColorToHTMLString.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Extras/ValueTransformers/COColorToHTMLString.m b/Extras/ValueTransformers/COColorToHTMLString.m index be32ccb5c..a32ed2a98 100644 --- a/Extras/ValueTransformers/COColorToHTMLString.m +++ b/Extras/ValueTransformers/COColorToHTMLString.m @@ -39,9 +39,9 @@ static CGFloat FractionFromHex(NSString *twoChars) NSColor *rgbColor = color; CGFloat a, r, g, b; - // NOTE: iOS does not support device-independent or generic color spaces + // NOTE: On iOS, UIColor uses sRGB color space by default #if !(TARGET_OS_IPHONE) - rgbColor = [color colorUsingColorSpaceName: NSCalibratedRGBColorSpace]; + rgbColor = [color colorUsingColorSpace: NSColorSpace.sRGBColorSpace]; #endif [rgbColor getRed: &r green: &g blue: &b alpha: &a]; @@ -62,7 +62,7 @@ static CGFloat FractionFromHex(NSString *twoChars) #if TARGET_OS_IPHONE return [UIColor colorWithRed: r green: g blue: b alpha: a]; #else - return [NSColor colorWithCalibratedRed: r green: g blue: b alpha: a]; + return [NSColor colorWithSRGBRed: r green: g blue: b alpha: a]; #endif } From 5aac8d4edf66fe2814befcf8e487771d649d5d78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Quentin=20Mathe=CC=81?= Date: Fri, 29 Oct 2021 15:47:23 +0200 Subject: [PATCH 6/9] Don't post distributed notifications in a mac sandboxed app --- CODistributedNotificationCenter.h | 38 ++++++++++++++ ...ter.m => CODistributedNotificationCenter.m | 4 +- CoreObject.xcodeproj/project.pbxproj | 24 +++++---- Store/COSQLiteStore.m | 9 +--- Undo/COUndoTrack.m | 2 +- Undo/COUndoTrackStore.m | 9 +--- iOS/NSDistributedNotificationCenter.h | 49 ------------------- 7 files changed, 60 insertions(+), 75 deletions(-) create mode 100644 CODistributedNotificationCenter.h rename iOS/NSDistributedNotificationCenter.m => CODistributedNotificationCenter.m (93%) delete mode 100644 iOS/NSDistributedNotificationCenter.h diff --git a/CODistributedNotificationCenter.h b/CODistributedNotificationCenter.h new file mode 100644 index 000000000..49317fac0 --- /dev/null +++ b/CODistributedNotificationCenter.h @@ -0,0 +1,38 @@ +/* + Copyright (C) 2014 Quentin Mathe + + Date: July 2014 + License: MIT (see COPYING) + */ + +#import + +/** + * @group Utilities + * @abstract Distributed notification center compatible with sandboxing. + * + * When sandboxing is enabled, posting a notification does nothing. + * + * For non-sandboxed applications on macOS, we use + * NSDistributedNotificationCenter to keep multiple store instances (using the + * same UUID) in sync, accross processes and inside the current process. For + * sandboxed applications on iOS or macOS, this is the same, except we don't + * support the 'accross processes' case. + * + * See also COSQLiteStore and COUndoTrackStore. + **/ +@interface CODistributedNotificationCenter : NSNotificationCenter +/** + * Returns the default distributed notification center. + */ ++ (CODistributedNotificationCenter *)defaultCenter; +/** + * Posts a notification with the given sender and info. + * + * deliverImmediately is ignored, and considered as YES all the time. + */ +- (void)postNotificationName: (NSString *)aName + object: (NSString *)aSender + userInfo: (NSDictionary *)userInfo + deliverImmediately: (BOOL)deliverImmediately; +@end diff --git a/iOS/NSDistributedNotificationCenter.m b/CODistributedNotificationCenter.m similarity index 93% rename from iOS/NSDistributedNotificationCenter.m rename to CODistributedNotificationCenter.m index 65c34ad7f..ce49c06ab 100644 --- a/iOS/NSDistributedNotificationCenter.m +++ b/CODistributedNotificationCenter.m @@ -5,7 +5,7 @@ License: MIT (see COPYING) */ -#import "NSDistributedNotificationCenter.h" +#import "CODistributedNotificationCenter.h" /** * @group iOS @@ -44,7 +44,9 @@ - (void)postNotificationName: (NSString *)aName userInfo: (NSDictionary *)userInfo deliverImmediately: (BOOL)deliverImmediately { +#if !(SANDBOXED) && !(TARGET_OS_IPHONE) [self postNotificationName: aName object: aSender userInfo: userInfo]; +#endif } @end diff --git a/CoreObject.xcodeproj/project.pbxproj b/CoreObject.xcodeproj/project.pbxproj index 400b1a39c..7b10ebeb1 100644 --- a/CoreObject.xcodeproj/project.pbxproj +++ b/CoreObject.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 6001FA89272C3255000FDD6A /* CODistributedNotificationCenter.m in Sources */ = {isa = PBXBuildFile; fileRef = 60882F1F197E629F00484033 /* CODistributedNotificationCenter.m */; }; 6002E21D197FD6B200AC9150 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 60882F24197EA24900484033 /* AppKit.framework */; }; 6002E21E197FD73A00AC9150 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 60882F24197EA24900484033 /* AppKit.framework */; }; 6002E280197FD90300AC9150 /* libSystem.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 60F91ED6197D2CA2009F47D7 /* libSystem.dylib */; }; @@ -108,9 +109,9 @@ 60882F1B197D50C000484033 /* COObjectToArchivedData.m in Sources */ = {isa = PBXBuildFile; fileRef = 608D25F5192B475200BB7461 /* COObjectToArchivedData.m */; }; 60882F1C197D50CA00484033 /* CORectToString.m in Sources */ = {isa = PBXBuildFile; fileRef = 6633F10D185515F1009CE6F7 /* CORectToString.m */; }; 60882F1D197D50CE00484033 /* CORectToString.h in Headers */ = {isa = PBXBuildFile; fileRef = 6633F10C185515F1009CE6F7 /* CORectToString.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 60882F20197E629F00484033 /* NSDistributedNotificationCenter.h in Headers */ = {isa = PBXBuildFile; fileRef = 60882F1E197E629F00484033 /* NSDistributedNotificationCenter.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 60882F21197E629F00484033 /* NSDistributedNotificationCenter.m in Sources */ = {isa = PBXBuildFile; fileRef = 60882F1F197E629F00484033 /* NSDistributedNotificationCenter.m */; }; - 60882F22197E62FC00484033 /* NSDistributedNotificationCenter.h in Headers */ = {isa = PBXBuildFile; fileRef = 60882F1E197E629F00484033 /* NSDistributedNotificationCenter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 60882F20197E629F00484033 /* CODistributedNotificationCenter.h in Headers */ = {isa = PBXBuildFile; fileRef = 60882F1E197E629F00484033 /* CODistributedNotificationCenter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 60882F21197E629F00484033 /* CODistributedNotificationCenter.m in Sources */ = {isa = PBXBuildFile; fileRef = 60882F1F197E629F00484033 /* CODistributedNotificationCenter.m */; }; + 60882F22197E62FC00484033 /* CODistributedNotificationCenter.h in Headers */ = {isa = PBXBuildFile; fileRef = 60882F1E197E629F00484033 /* CODistributedNotificationCenter.h */; settings = {ATTRIBUTES = (Public, ); }; }; 60882F25197EA24900484033 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 60882F24197EA24900484033 /* AppKit.framework */; }; 60882F27197EA25600484033 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 60882F26197EA25600484033 /* Foundation.framework */; }; 60882F29197EA26900484033 /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 60882F28197EA26900484033 /* libsqlite3.dylib */; }; @@ -1080,8 +1081,8 @@ 6083223619795D18008D9F9D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.0.sdk/System/Library/Frameworks/CoreGraphics.framework; sourceTree = DEVELOPER_DIR; }; 6083223819795D21008D9F9D /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.0.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; 6083223C19797DE2008D9F9D /* COCocoaTouchCompatibility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = COCocoaTouchCompatibility.h; path = iOS/COCocoaTouchCompatibility.h; sourceTree = SOURCE_ROOT; }; - 60882F1E197E629F00484033 /* NSDistributedNotificationCenter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NSDistributedNotificationCenter.h; path = iOS/NSDistributedNotificationCenter.h; sourceTree = SOURCE_ROOT; }; - 60882F1F197E629F00484033 /* NSDistributedNotificationCenter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NSDistributedNotificationCenter.m; path = iOS/NSDistributedNotificationCenter.m; sourceTree = SOURCE_ROOT; }; + 60882F1E197E629F00484033 /* CODistributedNotificationCenter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CODistributedNotificationCenter.h; sourceTree = SOURCE_ROOT; }; + 60882F1F197E629F00484033 /* CODistributedNotificationCenter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CODistributedNotificationCenter.m; sourceTree = SOURCE_ROOT; }; 60882F24197EA24900484033 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; 60882F26197EA25600484033 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 60882F28197EA26900484033 /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = usr/lib/libsqlite3.dylib; sourceTree = SDKROOT; }; @@ -1702,8 +1703,6 @@ isa = PBXGroup; children = ( 6083223C19797DE2008D9F9D /* COCocoaTouchCompatibility.h */, - 60882F1E197E629F00484033 /* NSDistributedNotificationCenter.h */, - 60882F1F197E629F00484033 /* NSDistributedNotificationCenter.m */, 60F91EC6197D1D1C009F47D7 /* main.m */, 6028484D1BBAB5820094CDB0 /* Default-568h@2x.png */, 60F91EC8197D1D7F009F47D7 /* TestCoreObject-Info.plist */, @@ -2105,6 +2104,8 @@ 6686BDC712592C1B0065DE1A /* Utilities */ = { isa = PBXGroup; children = ( + 60882F1E197E629F00484033 /* CODistributedNotificationCenter.h */, + 60882F1F197E629F00484033 /* CODistributedNotificationCenter.m */, 609C00E21704C42200D01AAB /* COError.h */, 609C00E31704C42200D01AAB /* COError.m */, 6612113E1821986B003AEC29 /* CODateSerialization.h */, @@ -2605,7 +2606,7 @@ 60E08D3019792FFA00D1B7AD /* COCommandUndeletePersistentRoot.h in Headers */, 60E08D0219792FFA00D1B7AD /* COBookmark.h in Headers */, 60E08D3219792FFA00D1B7AD /* COItemGraphEdit.h in Headers */, - 60882F20197E629F00484033 /* NSDistributedNotificationCenter.h in Headers */, + 60882F20197E629F00484033 /* CODistributedNotificationCenter.h in Headers */, 60B1568F19B861D3006D5EEF /* COObjectGraphContext+Debugging.h in Headers */, 60E08D6119792FFA00D1B7AD /* COObjectGraphContext+GarbageCollection.h in Headers */, 60E08D5C19792FFA00D1B7AD /* COStoreWriteRevision.h in Headers */, @@ -2653,7 +2654,7 @@ buildActionMask = 2147483647; files = ( 6036436C1B3800B400DC685B /* COHistoryCompaction.h in Headers */, - 60882F22197E62FC00484033 /* NSDistributedNotificationCenter.h in Headers */, + 60882F22197E62FC00484033 /* CODistributedNotificationCenter.h in Headers */, 609C00801704C2BA00D01AAB /* CORevision.h in Headers */, 609C00941704C3DA00D01AAB /* COEditingContext.h in Headers */, 603643841B394E8800DC685B /* COUndoTrackHistoryCompaction.h in Headers */, @@ -3320,7 +3321,7 @@ 60E08CBA19792F4600D1B7AD /* COBezierPath.m in Sources */, 60E08CB419792F4600D1B7AD /* COSQLiteStorePersistentRootBackingStore.m in Sources */, 60E08CE119792F4600D1B7AD /* COLeastCommonAncestor.m in Sources */, - 60882F21197E629F00484033 /* NSDistributedNotificationCenter.m in Sources */, + 60882F21197E629F00484033 /* CODistributedNotificationCenter.m in Sources */, 60E08CAB19792F4600D1B7AD /* CODictionary.m in Sources */, 60E08CDF19792F4600D1B7AD /* COSequenceModification.m in Sources */, 60E08CBF19792F4600D1B7AD /* COAttributedStringDiff.m in Sources */, @@ -3594,6 +3595,7 @@ 663CE29A17C07ED800E729F5 /* COCommandDeleteBranch.m in Sources */, 663CE29C17C07ED800E729F5 /* COCommandSetBranchMetadata.m in Sources */, 663CE29E17C07ED800E729F5 /* COCommandSetCurrentBranch.m in Sources */, + 6001FA89272C3255000FDD6A /* CODistributedNotificationCenter.m in Sources */, 663CE2A017C07ED800E729F5 /* COCommandSetCurrentVersionForBranch.m in Sources */, 663CE2A217C07ED800E729F5 /* COUndoTrackStore.m in Sources */, 663CE2B717C0B05900E729F5 /* COEditingContext+Undo.m in Sources */, @@ -4194,6 +4196,7 @@ DYLIB_COMPATIBILITY_VERSION = 0; DYLIB_CURRENT_VERSION = 5; FRAMEWORK_VERSION = A; + GCC_PREPROCESSOR_DEFINITIONS = "SANDBOXED=1"; INFOPLIST_FILE = CoreObjectInfo.plist; INSTALL_PATH = "@rpath"; OTHER_CFLAGS = ( @@ -4219,6 +4222,7 @@ DYLIB_COMPATIBILITY_VERSION = 0; DYLIB_CURRENT_VERSION = 5; FRAMEWORK_VERSION = A; + GCC_PREPROCESSOR_DEFINITIONS = "SANDBOXED=1"; INFOPLIST_FILE = CoreObjectInfo.plist; INSTALL_PATH = "@rpath"; OTHER_CFLAGS = ( diff --git a/Store/COSQLiteStore.m b/Store/COSQLiteStore.m index 84f387dc7..1476fc9d4 100644 --- a/Store/COSQLiteStore.m +++ b/Store/COSQLiteStore.m @@ -18,12 +18,7 @@ #import "COJSONSerialization.h" #import "COStoreTransaction.h" #import "COStoreAction.h" - -#if TARGET_OS_IPHONE - -#import "NSDistributedNotificationCenter.h" - -#endif +#import "CODistributedNotificationCenter.h" #import "FMDatabaseAdditions.h" @@ -1045,7 +1040,7 @@ - (void)postCommitNotificationsWithUserInfo: (NSDictionary *)userInfo object: self userInfo: userInfo]; - [[NSDistributedNotificationCenter defaultCenter] + [[CODistributedNotificationCenter defaultCenter] postNotificationName: COStorePersistentRootsDidChangeNotification object: [self.UUID stringValue] userInfo: userInfo diff --git a/Undo/COUndoTrack.m b/Undo/COUndoTrack.m index 0d78de69b..d0b030399 100644 --- a/Undo/COUndoTrack.m +++ b/Undo/COUndoTrack.m @@ -884,7 +884,7 @@ - (void)postNotificationsForTrackName: (NSString *)aTrack object: self userInfo: userInfo]; // FIXME: Implement distributed notification support - // [[NSDistributedNotificationCenter defaultCenter] postNotificationName: COStorePersistentRootDidChangeNotification + // [[CODistributedNotificationCenter defaultCenter] postNotificationName: COStorePersistentRootDidChangeNotification // object: [self.UUID stringValue] // userInfo: userInfo // deliverImmediately: NO]; diff --git a/Undo/COUndoTrackStore.m b/Undo/COUndoTrackStore.m index 7fec1fcd9..08bf14bc1 100644 --- a/Undo/COUndoTrackStore.m +++ b/Undo/COUndoTrackStore.m @@ -14,12 +14,7 @@ #import "COEndOfUndoTrackPlaceholderNode.h" #import "COJSONSerialization.h" #import "COSQLiteUtilities.h" - -#if TARGET_OS_IPHONE - -#import "NSDistributedNotificationCenter.h" - -#endif +#import "CODistributedNotificationCenter.h" /* For dispatch_get_current_queue() deprecated on iOS (to prevent to people to use it beside debugging) */ @@ -736,7 +731,7 @@ - (void)postCommitNotificationsWithUserInfo: (NSDictionary *)userInfo object: self userInfo: userInfo]; - [[NSDistributedNotificationCenter defaultCenter] + [[CODistributedNotificationCenter defaultCenter] postNotificationName: COUndoTrackStoreTrackDidChangeNotification object: [_db databasePath] userInfo: userInfo diff --git a/iOS/NSDistributedNotificationCenter.h b/iOS/NSDistributedNotificationCenter.h deleted file mode 100644 index c4d2c5464..000000000 --- a/iOS/NSDistributedNotificationCenter.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - Copyright (C) 2014 Quentin Mathe - - Date: July 2014 - License: MIT (see COPYING) - */ - -#import - -#if TARGET_OS_IPHONE - -/** - * @group iOS - * @abstract A fake distributed notification center that operates locally. - * - * This makes possible to support NSDistributedNotificationCenter API on iOS. - * - * On macOS, we use it to keep multiple store instances (using the same UUID) - * in sync, accross processes and inside the current process. On iOS, this is - * the same, except we don't support the 'accross processes' case. - * - * Note: A store cannot be accessed by multiple applications on iOS, due to the - * sandboxing restrictions. - * - * See also COSQLiteStore and COUndoTrackStore. - **/ -@interface CODistributedNotificationCenter : NSNotificationCenter -/** - * Returns the default distributed notification center. - */ -+ (CODistributedNotificationCenter *)defaultCenter; -/** - * Posts a notification with the given sender and info. - * - * deliverImmediately is ignored, and considered as YES all the time. - */ -- (void)postNotificationName: (NSString *)aName - object: (NSString *)aSender - userInfo: (NSDictionary *)userInfo - deliverImmediately: (BOOL)deliverImmediately; -@end - -/** - * AppStore approval process treats NSDistributedNotificationCenter as a private - * API, so we use another name internally. - */ -@compatibility_alias NSDistributedNotificationCenter CODistributedNotificationCenter; - -#endif From 124d2db2d517e0f0bff13553ac580cf5cc10d3fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Quentin=20Mathe=CC=81?= Date: Wed, 3 Nov 2021 14:05:43 +0100 Subject: [PATCH 7/9] Update COEditingContext to use CODistributedNotificationCenter --- Core/COEditingContext.m | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Core/COEditingContext.m b/Core/COEditingContext.m index 46eacadd7..2ee1d7b99 100644 --- a/Core/COEditingContext.m +++ b/Core/COEditingContext.m @@ -23,9 +23,7 @@ #import "COCrossPersistentRootDeadRelationshipCache.h" #import "CORevisionCache.h" #import "COStoreTransaction.h" -#if TARGET_OS_IPHONE -#import "NSDistributedNotificationCenter.h" -#endif +#import "CODistributedNotificationCenter.h" @implementation COEditingContext @@ -81,7 +79,7 @@ - (instancetype)initWithStore: (COSQLiteStore *)store name: COStorePersistentRootsDidChangeNotification object: _store]; - [[NSDistributedNotificationCenter defaultCenter] + [[CODistributedNotificationCenter defaultCenter] addObserver: self selector: @selector(distributedStorePersistentRootsDidChange:) name: COStorePersistentRootsDidChangeNotification @@ -117,7 +115,7 @@ - (instancetype)init - (void)dealloc { - [[NSDistributedNotificationCenter defaultCenter] removeObserver: self]; + [[CODistributedNotificationCenter defaultCenter] removeObserver: self]; [[NSNotificationCenter defaultCenter] removeObserver: self]; } From a7ab7e3750fbf98b8b949c52dfb1f066a8ce3380 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Quentin=20Mathe=CC=81?= Date: Thu, 4 Nov 2021 09:49:03 +0100 Subject: [PATCH 8/9] Fix broken tests involving notifications and keeping editing contexts in sync while using multiple store instances --- CODistributedNotificationCenter.h | 30 +++++++++++++--- CODistributedNotificationCenter.m | 60 +++++++++++++++++++++---------- 2 files changed, 66 insertions(+), 24 deletions(-) diff --git a/CODistributedNotificationCenter.h b/CODistributedNotificationCenter.h index 49317fac0..edb5e0cbf 100644 --- a/CODistributedNotificationCenter.h +++ b/CODistributedNotificationCenter.h @@ -7,32 +7,52 @@ #import +NS_ASSUME_NONNULL_BEGIN + /** * @group Utilities * @abstract Distributed notification center compatible with sandboxing. * - * When sandboxing is enabled, posting a notification does nothing. + * When sandboxing is enabled, posting a distributed notification results + * in a normal notification. * * For non-sandboxed applications on macOS, we use * NSDistributedNotificationCenter to keep multiple store instances (using the * same UUID) in sync, accross processes and inside the current process. For * sandboxed applications on iOS or macOS, this is the same, except we don't * support the 'accross processes' case. + * + * We cannot ignore distributed notifications in a sandboxed app, because we + * support keeping in sync two editing contexts backed by two distinct stores + * objects with the same UUID. * * See also COSQLiteStore and COUndoTrackStore. **/ -@interface CODistributedNotificationCenter : NSNotificationCenter +@interface CODistributedNotificationCenter : NSObject /** * Returns the default distributed notification center. */ + (CODistributedNotificationCenter *)defaultCenter; +/** + * Adds an observer for the given selector, notification name and object identifier. + */ +- (void)addObserver: (id)observer + selector: (SEL)aSelector + name: (nullable NSNotificationName)aName + object: (nullable NSString *)anObject; +/** + * Removes an observer. + */ +- (void)removeObserver: (id)observer; /** * Posts a notification with the given sender and info. * * deliverImmediately is ignored, and considered as YES all the time. */ -- (void)postNotificationName: (NSString *)aName - object: (NSString *)aSender - userInfo: (NSDictionary *)userInfo +- (void)postNotificationName: (nullable NSNotificationName)aName + object: (nullable NSString *)aSender + userInfo: (nullable NSDictionary *)userInfo deliverImmediately: (BOOL)deliverImmediately; @end + +NS_ASSUME_NONNULL_END diff --git a/CODistributedNotificationCenter.m b/CODistributedNotificationCenter.m index ce49c06ab..bd23cba11 100644 --- a/CODistributedNotificationCenter.m +++ b/CODistributedNotificationCenter.m @@ -7,21 +7,6 @@ #import "CODistributedNotificationCenter.h" -/** - * @group iOS - * @abstract A fake distributed notification center that operates locally. - * - * This makes possible to support NSDistributedNotificationCenter API on iOS. - * - * On macOS, we use it to keep multiple store instances (using the same UUID) - * in sync, accross processes and inside the current process. On iOS, this is - * the same, except we don't support the 'accross processes' case. - * - * Note: A store cannot be accessed by multiple applications on iOS, due to the - * sandboxing restrictions. - * - * See also COSQLiteStore and COUndoTrackStore. - **/ @implementation CODistributedNotificationCenter static CODistributedNotificationCenter *defaultCenter = nil; @@ -39,13 +24,50 @@ + (CODistributedNotificationCenter *)defaultCenter return defaultCenter; } -- (void)postNotificationName: (NSString *)aName - object: (NSString *)aSender - userInfo: (NSDictionary *)userInfo +- (void)addObserver: (id)observer + selector: (SEL)aSelector + name: (nullable NSNotificationName)aName + object: (nullable NSString *)anObject +{ +#if !(SANDBOXED) && !(TARGET_OS_IPHONE) + [[NSDistributedNotificationCenter defaultCenter] + addObserver: observer + selector: aSelector + name: aName + object: anObject]; +#else + [[NSNotificationCenter defaultCenter] + addObserver: observer + selector: aSelector + name: aName + object: anObject]; +#endif +} + +- (void)removeObserver: (id)observer { +#if !(SANDBOXED) && !(TARGET_OS_IPHONE) + [[NSDistributedNotificationCenter defaultCenter] removeObserver: observer]; +#else + [[NSNotificationCenter defaultCenter] removeObserver: observer]; +#endif +} + +- (void)postNotificationName: (nullable NSNotificationName)aName + object: (nullable NSString *)aSender + userInfo: (nullable NSDictionary *)userInfo deliverImmediately: (BOOL)deliverImmediately { #if !(SANDBOXED) && !(TARGET_OS_IPHONE) - [self postNotificationName: aName object: aSender userInfo: userInfo]; + [[NSDistributedNotificationCenter defaultCenter] + postNotificationName: aName + object: aSender + userInfo: userInfo + deliverImmediately: deliverImmediately]; +#else + [[NSNotificationCenter defaultCenter] + postNotificationName: aName + object: aSender + userInfo: userInfo]; #endif } From 7773f6a4f8479aa98126038b94e0a3243cdd6144 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Quentin=20Mathe=CC=81?= Date: Thu, 4 Nov 2021 10:07:03 +0100 Subject: [PATCH 9/9] Apply changes from PR #74 --- ...OCrossPersistentRootDeadRelationshipCache.h | 2 +- ...OCrossPersistentRootDeadRelationshipCache.m | 8 -------- Core/COPrimitiveCollection.m | 18 +----------------- Debugging/COSQLiteStore+Graphviz.m | 9 +++------ StorageDataModel/COItem+JSON.m | 18 +----------------- Tests/StorageDataModel/TestItem.m | 5 +---- Tests/TestCommon.m | 2 -- Undo/COUndoTrackStore+Private.h | 10 +++++----- 8 files changed, 12 insertions(+), 60 deletions(-) diff --git a/Core/COCrossPersistentRootDeadRelationshipCache.h b/Core/COCrossPersistentRootDeadRelationshipCache.h index c809b80c1..6f02829db 100644 --- a/Core/COCrossPersistentRootDeadRelationshipCache.h +++ b/Core/COCrossPersistentRootDeadRelationshipCache.h @@ -59,7 +59,7 @@ NS_ASSUME_NONNULL_BEGIN * * For referring object graph contexts, when unloaded or finalized, the * deallocation will trigger their removal of their inner objects from the hash - * tables in the cache on 10.8 or iOS 6 or higher, but not on 10.7. + * tables in the cache on 10.8 or iOS 6 or higher, which we require. */ - (void)removePath: (COPath *)aPath; diff --git a/Core/COCrossPersistentRootDeadRelationshipCache.m b/Core/COCrossPersistentRootDeadRelationshipCache.m index 4e248b57d..8091c11f6 100644 --- a/Core/COCrossPersistentRootDeadRelationshipCache.m +++ b/Core/COCrossPersistentRootDeadRelationshipCache.m @@ -16,11 +16,7 @@ - (instancetype)init { SUPERINIT; _pathToReferringObjects = [NSMutableDictionary new]; -#if GNUSTEP - _referringObjectToPaths = [NSMapTable mapTableWithWeakToStrongObjects]; -#else _referringObjectToPaths = [NSMapTable weakToStrongObjectsMapTable]; -#endif return self; } @@ -35,11 +31,7 @@ - (void)addReferringObject: (COObject *)aReferrer // FIXME: If we don't ditch 10.7 support, we need a reverse mapping // from each referringObject to a path set, that can be used to remove // the referring objects when their object graph context is discarded. -#ifdef GNUSTEP - referringObjects = [NSHashTable hashTableWithWeakObjects]; -#else referringObjects = [NSHashTable weakObjectsHashTable]; -#endif _pathToReferringObjects[aPath] = referringObjects; } diff --git a/Core/COPrimitiveCollection.m b/Core/COPrimitiveCollection.m index 801422afd..17897594e 100644 --- a/Core/COPrimitiveCollection.m +++ b/Core/COPrimitiveCollection.m @@ -83,11 +83,7 @@ - (BOOL)isMutable - (NSPointerArray *)makeBacking { -#ifdef GNUSTEP - return [NSPointerArray pointerArrayWithStrongObjects]; -#else return [NSPointerArray strongObjectsPointerArray]; -#endif } - (instancetype)init @@ -250,7 +246,7 @@ - (void)insertObject: (id)anObject atIndex: (NSUInteger)index COThrowExceptionIfNotMutable(_permanentlyMutable, _temporaryMutable); COThrowExceptionIfOutOfBounds(self, index, YES); - // NSPointerArray on 10.7 doesn't allow inserting at the end using index == count, so + // NSPointerArray on 10.9 (at least) doesn't allow inserting at the end using index == count, so // call addPointer in that case as a workaround. if (index == _externalIndexToBackingIndex.count) { @@ -366,20 +362,12 @@ @implementation COUnsafeRetainedMutableArray - (NSPointerArray *)makeBacking { -#ifdef GNUSTEP - return [NSPointerArray pointerArrayWithWeakObjects]; -#else return [NSPointerArray weakObjectsPointerArray]; -#endif } - (NSHashTable *)makeBackingHashTable { -#ifdef GNUSTEP - return [NSHashTable hashTableWithWeakObjects]; -#else return [NSHashTable weakObjectsHashTable]; -#endif } - (instancetype)initWithObjects: (const id[])objects count: (NSUInteger)count @@ -672,11 +660,7 @@ @implementation COUnsafeRetainedMutableSet - (NSHashTable *)makeBacking { -#ifdef GNUSTEP - return [NSHashTable hashTableWithWeakObjects]; -#else return [NSHashTable weakObjectsHashTable]; -#endif } @end diff --git a/Debugging/COSQLiteStore+Graphviz.m b/Debugging/COSQLiteStore+Graphviz.m index 9d43ec196..7c4b08e10 100644 --- a/Debugging/COSQLiteStore+Graphviz.m +++ b/Debugging/COSQLiteStore+Graphviz.m @@ -178,12 +178,9 @@ void COViewDOTGraphFile(NSString *dotFilePath) { continue; } - - // NOTE: Using NSTask rather than system() breaks 'po [objectGraphContext showGraph]' in LLDB on 10.7 - system([[NSString stringWithFormat: @"%@ -Tpdf '%@' -o '%@'", - executablePath, - dotFilePath, - pdfPath] UTF8String]); + NSTask *task = [NSTask launchedTaskWithLaunchPath: executablePath + arguments: @[@"-Tpdf", dotFilePath, @"-o", pdfPath]]; + [task waitUntilExit]; [[NSWorkspace sharedWorkspace] openFile: pdfPath]; break; } diff --git a/StorageDataModel/COItem+JSON.m b/StorageDataModel/COItem+JSON.m index bd5d7c0e2..be73d9a02 100644 --- a/StorageDataModel/COItem+JSON.m +++ b/StorageDataModel/COItem+JSON.m @@ -167,22 +167,6 @@ static id plistValueForValue(id aValue, COType aType) // JSON-compatible plist -> COItem attribute value -/* - * Returning the parsed value as a NSNumber rather a NSDecimalNumber to ensure - * the rounding is the same than the serialized NSNumber object. - * - * Without this workaround, 123.456789012 roundtrip doesn't succeed on 10.7 (see - * -testJSONDoubleEquality in TestItem.m)). - * - * For 123.456789012, NSJSONSerialization returns a NSDecimalNumber, but the - * rounding doesn't produce the same internal representation than a NSNumber - * initialized with the same double value. - */ -static inline NSNumber *basicNumberFromDecimalNumber(NSNumber *aValue) -{ - return @(aValue.description.doubleValue); -} - static id valueForPrimitivePlistValue(id aValue, COType aType) { if (aValue == [NSNull null]) @@ -195,7 +179,7 @@ static id valueForPrimitivePlistValue(id aValue, COType aType) case kCOTypeInt64: return aValue; case kCOTypeDouble: - return basicNumberFromDecimalNumber(aValue); + return aValue; case kCOTypeString: return aValue; case kCOTypeAttachment: diff --git a/Tests/StorageDataModel/TestItem.m b/Tests/StorageDataModel/TestItem.m index e04a0077e..364f8d1d4 100644 --- a/Tests/StorageDataModel/TestItem.m +++ b/Tests/StorageDataModel/TestItem.m @@ -82,16 +82,13 @@ - (void)testJSONDoubleEquality NSNumber *newValueFromDesc = @(roundTripValue.description.doubleValue); #ifndef GNUSTEP - // NOTE: Doesn't matter on GNUstep since newValue is not a NSDecimalNumber, - // and we don't have to convert it into a NSDoubleNumber (unlike on 10.7). + // NOTE: Doesn't matter on GNUstep since newValue is not a NSDecimalNumber. UKTrue([[NSDecimalNumber defaultBehavior] scale] == NSDecimalNoScale); #endif NSLog(@"Double representation in JSON: %@", [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding]); - /* Rounding is visible in the ouput for numbers that contain more than two - decimals on 10.7 (e.g. 123.45 output is the same for all numbers). */ NSLog(@"value doubleValue: %.20f, description: %@, class: %@", value.doubleValue, value, [value class]); NSLog(@"decimalValue doubleValue: %.20f, description: %@, class: %@", diff --git a/Tests/TestCommon.m b/Tests/TestCommon.m index 1e0052398..22fffeb47 100644 --- a/Tests/TestCommon.m +++ b/Tests/TestCommon.m @@ -91,8 +91,6 @@ - (instancetype)init - (void)dealloc { #ifdef DELETE_STORE_AFTER_EACH_TEST_METHOD - // FIXME: For Mac OS X 10.7, this is unsupported, SQLite disk errors - // (DB Error: 10 "disk I/O error") appear in TestStoreSQLite.m. [[self class] deleteStores]; #endif } diff --git a/Undo/COUndoTrackStore+Private.h b/Undo/COUndoTrackStore+Private.h index 67d63afc7..5dc3bd061 100644 --- a/Undo/COUndoTrackStore+Private.h +++ b/Undo/COUndoTrackStore+Private.h @@ -11,22 +11,22 @@ @class FMDatabase; @class ETUUID; -NSString *const COUndoTrackStoreTrackDidChangeNotification; +extern NSString *const COUndoTrackStoreTrackDidChangeNotification; // User info keys for COUndoTrackStoreTrackDidChangeNotification -NSString *const COUndoTrackStoreTrackName; +extern NSString *const COUndoTrackStoreTrackName; /** * UUID string */ -NSString *const COUndoTrackStoreTrackHeadCommandUUID; +extern NSString *const COUndoTrackStoreTrackHeadCommandUUID; /** * NSNull or UUID string */ -NSString *const COUndoTrackStoreTrackCurrentCommandUUID; +extern NSString *const COUndoTrackStoreTrackCurrentCommandUUID; /** * NSNumber boolean */ -NSString *const COUndoTrackStoreTrackCompacted; +extern NSString *const COUndoTrackStoreTrackCompacted; @interface COUndoTrackSerializedCommand : NSObject