Navigation Menu

Skip to content

Commit

Permalink
Merge pull request #657 from bgeorgescu/patch-1
Browse files Browse the repository at this point in the history
Fix NIAttributedLabel race condition relating to deferred auto link detection
  • Loading branch information
stephanemoore committed Aug 30, 2016
2 parents cb2c27b + bcd8ff7 commit 7b33cc0
Showing 1 changed file with 16 additions and 15 deletions.
31 changes: 16 additions & 15 deletions src/attributedlabel/src/NIAttributedLabel.m
Expand Up @@ -214,7 +214,7 @@ @interface NIAttributedLabel() <UIActionSheetDelegate>

@property (nonatomic) CTFrameRef textFrame; // CFType, manually managed lifetime, see setter.

@property (assign) BOOL detectingLinks; // Atomic.
@property (nonatomic, assign) NSInteger linkDetectionRequestID;
@property (nonatomic) BOOL linksHaveBeenDetected;
@property (nonatomic, copy) NSArray* detectedlinkLocations;
@property (nonatomic, strong) NSMutableArray* explicitLinkLocations; // Of NSTextCheckingResult.
Expand Down Expand Up @@ -390,6 +390,7 @@ - (void)setAttributedText:(NSAttributedString *)attributedText {
// Clear the link caches.
self.detectedlinkLocations = nil;
self.linksHaveBeenDetected = NO;
self.linkDetectionRequestID++;
[self removeAllExplicitLinks];

// Remove all images.
Expand Down Expand Up @@ -667,22 +668,22 @@ - (NSArray *)_matchesFromAttributedString:(NSString *)string {
}

- (void)_deferLinkDetection {
if (!self.detectingLinks) {
self.detectingLinks = YES;

NSString* string = [self.mutableAttributedString.string copy];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSArray* matches = [self _matchesFromAttributedString:string];
self.detectingLinks = NO;

dispatch_async(dispatch_get_main_queue(), ^{
self.detectedlinkLocations = matches;
self.linksHaveBeenDetected = YES;
self.linkDetectionRequestID++;
const NSInteger linkDetectionRequestID = self.linkDetectionRequestID;
NSString* string = [self.mutableAttributedString.string copy];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSArray* matches = [self _matchesFromAttributedString:string];

dispatch_async(dispatch_get_main_queue(), ^{
if (self.linkDetectionRequestID != linkDetectionRequestID) {
return;
}
self.detectedlinkLocations = matches;
self.linksHaveBeenDetected = YES;

[self attributedTextDidChange];
});
[self attributedTextDidChange];
});
}
});
}

// Use an NSDataDetector to find any implicit links in the text. The results are cached until
Expand Down

0 comments on commit 7b33cc0

Please sign in to comment.