Last active
December 20, 2015 22:29
-
-
Save gcox/6205233 to your computer and use it in GitHub Desktop.
NSArrayController with throttled rearrangement When frequently changing objects monitored by an NSArrayController with auto rearrangement enabled, you can quickly run into an annoying performance issue caused by the array controller rearranging with unnecessary frequency. This subclass allows you to temporarily suspend rearrangement and/or throt…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@interface TWNSArrayController : NSArrayController | |
@property (nonatomic) BOOL throttleRearrangement; | |
@property (nonatomic) CGFloat rearrangementThrottleInterval; | |
-(void)suspendRearrangement; | |
-(void)resumeRearrangement; | |
@end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@implementation TWNSArrayController { | |
BOOL _canRearrange; | |
int _suspensionRequestCount; | |
BOOL _pendingRearrangement; | |
BOOL _throttleIntervalPassed; | |
NSTimer *_canRearrangeTimer; | |
} | |
-(id)init { | |
if ((self = [super init])) { | |
_canRearrange = YES; | |
_throttleIntervalPassed = YES; | |
_suspensionRequestCount = 0; | |
_rearrangementThrottleInterval = 1; | |
} | |
return self; | |
} | |
-(void)suspendRearrangement { | |
_suspensionRequestCount += 1; | |
_canRearrange = NO; | |
} | |
-(void)resumeRearrangement { | |
_suspensionRequestCount -= 1; | |
if (_suspensionRequestCount < 0) // Unbalanced call to resumeRearrangement | |
_suspensionRequestCount = 0; | |
if (_suspensionRequestCount == 0) { | |
_canRearrange = YES; | |
if (_pendingRearrangement) | |
self rearrangeObjects]; | |
} | |
} | |
-(void)rearrangeObjects { | |
[_canRearrangeTimer invalidate]; | |
if (!_canRearrange) { | |
_pendingRearrangement = YES; | |
return; | |
} | |
_pendingRearrangement = NO; | |
_canRearrangeTimer = [NSTimer scheduledTimerWithTimeInterval:self.rearrangementThrottleInterval | |
target:self | |
selector:@selector(throttleIntervalPassed:) | |
userInfo:nil | |
repeats:NO]; | |
if (!_throttleIntervalPassed && self.throttleRearrangement) | |
return; | |
_throttleIntervalPassed = NO; | |
[super rearrangeObjects]; | |
} | |
-(void)throttleIntervalPassed:(NSTimer *)timer { | |
_throttleIntervalPassed = YES; | |
if (self.throttleRearrangement && _pendingRearrangement) | |
[self rearrangeObjects]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment