Add locking to ASControlNode

This commit is contained in:
Michael Schneider
2016-02-07 17:18:24 -08:00
parent 06bdcd0049
commit ef95394bac
2 changed files with 20 additions and 7 deletions

View File

@@ -49,7 +49,7 @@
058D09C1195D04C000B7D73C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 058D09C0195D04C000B7D73C /* UIKit.framework */; };
058D09C4195D04C000B7D73C /* libAsyncDisplayKit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 058D09AC195D04C000B7D73C /* libAsyncDisplayKit.a */; };
058D09CA195D04C000B7D73C /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 058D09C8195D04C000B7D73C /* InfoPlist.strings */; };
058D0A13195D050800B7D73C /* ASControlNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 058D09D6195D050800B7D73C /* ASControlNode.m */; };
058D0A13195D050800B7D73C /* ASControlNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 058D09D6195D050800B7D73C /* ASControlNode.mm */; };
058D0A14195D050800B7D73C /* ASDisplayNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 058D09D9195D050800B7D73C /* ASDisplayNode.mm */; };
058D0A15195D050800B7D73C /* ASDisplayNodeExtras.mm in Sources */ = {isa = PBXBuildFile; fileRef = 058D09DC195D050800B7D73C /* ASDisplayNodeExtras.mm */; };
058D0A16195D050800B7D73C /* ASImageNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 058D09DE195D050800B7D73C /* ASImageNode.mm */; };
@@ -379,7 +379,7 @@
B35061F61B010EFD0018CF92 /* ASCollectionView.mm in Sources */ = {isa = PBXBuildFile; fileRef = AC3C4A501A1139C100143C57 /* ASCollectionView.mm */; };
B35061F71B010EFD0018CF92 /* ASCollectionViewProtocols.h in Headers */ = {isa = PBXBuildFile; fileRef = AC3C4A531A113EEC00143C57 /* ASCollectionViewProtocols.h */; settings = {ATTRIBUTES = (Public, ); }; };
B35061F81B010EFD0018CF92 /* ASControlNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 058D09D5195D050800B7D73C /* ASControlNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
B35061F91B010EFD0018CF92 /* ASControlNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 058D09D6195D050800B7D73C /* ASControlNode.m */; };
B35061F91B010EFD0018CF92 /* ASControlNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 058D09D6195D050800B7D73C /* ASControlNode.mm */; };
B35061FA1B010EFD0018CF92 /* ASControlNode+Subclasses.h in Headers */ = {isa = PBXBuildFile; fileRef = 058D09D7195D050800B7D73C /* ASControlNode+Subclasses.h */; settings = {ATTRIBUTES = (Public, ); }; };
B35061FB1B010EFD0018CF92 /* ASDisplayNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 058D09D8195D050800B7D73C /* ASDisplayNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
B35061FC1B010EFD0018CF92 /* ASDisplayNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 058D09D9195D050800B7D73C /* ASDisplayNode.mm */; };
@@ -579,7 +579,7 @@
058D09C7195D04C000B7D73C /* AsyncDisplayKitTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "AsyncDisplayKitTests-Info.plist"; sourceTree = "<group>"; };
058D09C9195D04C000B7D73C /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
058D09D5195D050800B7D73C /* ASControlNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASControlNode.h; sourceTree = "<group>"; };
058D09D6195D050800B7D73C /* ASControlNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASControlNode.m; sourceTree = "<group>"; };
058D09D6195D050800B7D73C /* ASControlNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASControlNode.mm; sourceTree = "<group>"; };
058D09D7195D050800B7D73C /* ASControlNode+Subclasses.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASControlNode+Subclasses.h"; sourceTree = "<group>"; };
058D09D8195D050800B7D73C /* ASDisplayNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = ASDisplayNode.h; sourceTree = "<group>"; };
058D09D9195D050800B7D73C /* ASDisplayNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASDisplayNode.mm; sourceTree = "<group>"; };
@@ -952,7 +952,7 @@
DEC146B41C37A16A004A0EE7 /* ASCollectionInternal.h */,
DEC146B51C37A16A004A0EE7 /* ASCollectionInternal.m */,
058D09D5195D050800B7D73C /* ASControlNode.h */,
058D09D6195D050800B7D73C /* ASControlNode.m */,
058D09D6195D050800B7D73C /* ASControlNode.mm */,
DECBD6E51BE56E1900CF4905 /* ASButtonNode.h */,
DECBD6E61BE56E1900CF4905 /* ASButtonNode.mm */,
058D09D7195D050800B7D73C /* ASControlNode+Subclasses.h */,
@@ -1798,7 +1798,7 @@
DBC452DC1C5BF64600B16017 /* NSArray+Diffing.m in Sources */,
AC3C4A521A1139C100143C57 /* ASCollectionView.mm in Sources */,
205F0E1E1B373A2C007741D0 /* ASCollectionViewLayoutController.mm in Sources */,
058D0A13195D050800B7D73C /* ASControlNode.m in Sources */,
058D0A13195D050800B7D73C /* ASControlNode.mm in Sources */,
464052211A3F83C40061C0BA /* ASDataController.mm in Sources */,
B30BF6531C5964B0004FCD53 /* ASLayoutManager.m in Sources */,
05A6D05B19D0EB64002DD95E /* ASDealloc2MainObject.m in Sources */,
@@ -1940,7 +1940,7 @@
18C2ED831B9B7DE800F627B3 /* ASCollectionNode.mm in Sources */,
B35061F61B010EFD0018CF92 /* ASCollectionView.mm in Sources */,
509E68641B3AEDB7009B9150 /* ASCollectionViewLayoutController.mm in Sources */,
B35061F91B010EFD0018CF92 /* ASControlNode.m in Sources */,
B35061F91B010EFD0018CF92 /* ASControlNode.mm in Sources */,
B35062181B010EFD0018CF92 /* ASDataController.mm in Sources */,
B350621A1B010EFD0018CF92 /* ASDealloc2MainObject.m in Sources */,
34EFC75C1B701BD200AD841F /* ASDimension.mm in Sources */,

View File

@@ -8,6 +8,7 @@
#import "ASControlNode.h"
#import "ASControlNode+Subclasses.h"
#import "ASThread.h"
// UIControl allows dragging some distance outside of the control itself during
// tracking. This value depends on the device idiom (25 or 70 points), so
@@ -21,6 +22,8 @@
@interface ASControlNode ()
{
@private
ASDN::RecursiveMutex _controlLock;
// Control Attributes
BOOL _enabled;
BOOL _highlighted;
@@ -217,10 +220,12 @@ void _ASEnumerateControlEventsIncludedInMaskWithBlock(ASControlNodeEvent mask, v
NSParameterAssert(action);
NSParameterAssert(controlEventMask != 0);
ASDN::MutexLocker l(_controlLock);
// Convert nil to [NSNull null] so that it can be used as a key for NSMapTable.
if (!target)
target = [NSNull null];
if (!_controlEventDispatchTable) {
_controlEventDispatchTable = [[NSMutableDictionary alloc] initWithCapacity:kASControlNodeEventDispatchTableInitialCapacity]; // enough to handle common types without re-hashing the dictionary when adding entries.
}
@@ -262,6 +267,8 @@ void _ASEnumerateControlEventsIncludedInMaskWithBlock(ASControlNodeEvent mask, v
NSParameterAssert(target);
NSParameterAssert(controlEvent != 0 && controlEvent != ASControlNodeEventAllEvents);
ASDN::MutexLocker l(_controlLock);
// Grab the event dispatch table for this event.
NSMapTable *eventDispatchTable = [_controlEventDispatchTable objectForKey:_ASControlNodeEventKeyForControlEvent(controlEvent)];
if (!eventDispatchTable)
@@ -273,6 +280,8 @@ void _ASEnumerateControlEventsIncludedInMaskWithBlock(ASControlNodeEvent mask, v
- (NSSet *)allTargets
{
ASDN::MutexLocker l(_controlLock);
NSMutableSet *targets = [[NSMutableSet alloc] init];
// Look at each event...
@@ -289,6 +298,8 @@ void _ASEnumerateControlEventsIncludedInMaskWithBlock(ASControlNodeEvent mask, v
- (void)removeTarget:(id)target action:(SEL)action forControlEvents:(ASControlNodeEvent)controlEventMask
{
NSParameterAssert(controlEventMask != 0);
ASDN::MutexLocker l(_controlLock);
// Enumerate the events in the mask, removing the target-action pair for each control event included in controlEventMask.
_ASEnumerateControlEventsIncludedInMaskWithBlock(controlEventMask, ^
@@ -341,6 +352,8 @@ void _ASEnumerateControlEventsIncludedInMaskWithBlock(ASControlNodeEvent mask, v
- (void)sendActionsForControlEvents:(ASControlNodeEvent)controlEvents withEvent:(UIEvent *)event
{
NSParameterAssert(controlEvents != 0);
ASDN::MutexLocker l(_controlLock);
// Enumerate the events in the mask, invoking the target-action pairs for each.
_ASEnumerateControlEventsIncludedInMaskWithBlock(controlEvents, ^