[ASMapNode] snapshot can be triggered before layout and cause exception (e.g. setAnnotations)

This commit is contained in:
Hannah Troisi 2016-04-14 23:05:35 -07:00
parent 83a3a835b9
commit c981aeb09d
2 changed files with 22 additions and 2 deletions

View File

@ -89,7 +89,7 @@ NS_ASSUME_NONNULL_BEGIN
* @discussion Gives a chance for subclasses to perform actions after the subclass and superclass have finished laying
* out.
*/
- (void)layoutDidFinish;
- (void)layoutDidFinish ASDISPLAYNODE_REQUIRES_SUPER;
/**
* @abstract Called on a background thread if !isNodeLoaded - called on the main thread if isNodeLoaded.
@ -97,7 +97,7 @@ NS_ASSUME_NONNULL_BEGIN
* @discussion When the .calculatedLayout property is set to a new ASLayout (directly from -calculateLayoutThatFits: or
* calculated via use of -layoutSpecThatFits:), subclasses may inspect it here.
*/
- (void)calculatedLayoutDidChange;
- (void)calculatedLayoutDidChange ASDISPLAYNODE_REQUIRES_SUPER;
/** @name Layout calculation */

View File

@ -14,11 +14,13 @@
#import <AsyncDisplayKit/ASCenterLayoutSpec.h>
#import <AsyncDisplayKit/ASThread.h>
#import <AsyncDisplayKit/ASInternalHelpers.h>
#import <AsyncDisplayKit/ASLayout.h>
@interface ASMapNode()
{
ASDN::RecursiveMutex _propertyLock;
MKMapSnapshotter *_snapshotter;
BOOL _snapshotNeeded;
NSArray *_annotations;
CLLocationCoordinate2D _centerCoordinateOfMap;
}
@ -159,6 +161,15 @@
- (void)takeSnapshot
{
// do not trigger snapshot before layout
ASLayout *layout = self.calculatedLayout;
if (layout == nil || CGSizeEqualToSize(CGSizeZero, layout.size)) {
_snapshotNeeded = YES;
return;
}
_snapshotNeeded = NO;
if (!_snapshotter) {
[self setUpSnapshotter];
}
@ -307,6 +318,15 @@
return size;
}
- (void)calculatedLayoutDidChange
{
[super calculatedLayoutDidChange];
if (_snapshotNeeded) {
[self takeSnapshot];
}
}
// -layout isn't usually needed over -layoutSpecThatFits, but this way we can avoid a needless node wrapper for MKMapView.
- (void)layout
{