Skip to content

Instantly share code, notes, and snippets.

@gcox
Last active December 20, 2015 22:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gcox/6205233 to your computer and use it in GitHub Desktop.
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…
@interface TWNSArrayController : NSArrayController
@property (nonatomic) BOOL throttleRearrangement;
@property (nonatomic) CGFloat rearrangementThrottleInterval;
-(void)suspendRearrangement;
-(void)resumeRearrangement;
@end
@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