Review changes for kvo cleanliness
This commit is contained in:
parent
271167d50d
commit
987c178c35
@ -12,19 +12,19 @@ public extension MVMCoreAlertHandler {
|
|||||||
|
|
||||||
/// Re-evaluates the queue operations
|
/// Re-evaluates the queue operations
|
||||||
@objc func reevaluteQueue() {
|
@objc func reevaluteQueue() {
|
||||||
var highestReadyOperation: MVMCoreTopAlertOperation?
|
var higherPriorityOperationIsReady = false
|
||||||
var executingOperation: MVMCoreTopAlertOperation?
|
var executingOperation: MVMCoreTopAlertOperation?
|
||||||
|
let pageType = (MVMCoreUISplitViewController.main()?.getCurrentDetailViewController() as? MVMCoreViewControllerProtocol)?.pageType
|
||||||
let sortedOperations = topAlertQueue.operations.sorted { $0.queuePriority.rawValue > $1.queuePriority.rawValue }
|
let sortedOperations = topAlertQueue.operations.sorted { $0.queuePriority.rawValue > $1.queuePriority.rawValue }
|
||||||
for case let operation as MVMCoreTopAlertOperation in sortedOperations {
|
for case let operation as MVMCoreTopAlertOperation in sortedOperations {
|
||||||
guard !operation.isCancelled,
|
guard !operation.isCancelled,
|
||||||
!operation.isFinished else { continue }
|
!operation.isFinished else { continue }
|
||||||
operation.refreshReady()
|
updatePageReadiness(for: operation, with: pageType)
|
||||||
if operation.isReady,
|
|
||||||
highestReadyOperation == nil {
|
|
||||||
highestReadyOperation = operation
|
|
||||||
}
|
|
||||||
if operation.isExecuting {
|
if operation.isExecuting {
|
||||||
executingOperation = operation
|
executingOperation = operation
|
||||||
|
} else if operation.isReady,
|
||||||
|
executingOperation == nil {
|
||||||
|
higherPriorityOperationIsReady = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
guard let currentOperation = executingOperation else { return }
|
guard let currentOperation = executingOperation else { return }
|
||||||
@ -37,8 +37,7 @@ public extension MVMCoreAlertHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If the highest priority operation is not executing, and the executing operation is persistent, cancel it.
|
// If the highest priority operation is not executing, and the executing operation is persistent, cancel it.
|
||||||
if let newOperation = highestReadyOperation,
|
if higherPriorityOperationIsReady,
|
||||||
currentOperation != newOperation,
|
|
||||||
currentOperation.topAlertObject.persistent {
|
currentOperation.topAlertObject.persistent {
|
||||||
currentOperation.reAddAfterCancel = true
|
currentOperation.reAddAfterCancel = true
|
||||||
currentOperation.cancel()
|
currentOperation.cancel()
|
||||||
@ -50,6 +49,20 @@ public extension MVMCoreAlertHandler {
|
|||||||
NotificationCenter.default.addObserver(self, selector: #selector(viewControllerChanged(notification:)), name: NSNotification.Name(rawValue: MVMCoreNotificationViewControllerChanged), object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(viewControllerChanged(notification:)), name: NSNotification.Name(rawValue: MVMCoreNotificationViewControllerChanged), object: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Updates the operation isDisplayable based on the page type.
|
||||||
|
private func updatePageReadiness(for topOperation: MVMCoreTopAlertOperation, with pageType: String?) {
|
||||||
|
guard let pages = topOperation.topAlertObject.json?.optionalArrayForKey("pages") as? [String],
|
||||||
|
pages.count != 0 else {
|
||||||
|
topOperation.isDisplayable = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
guard let pageType = pageType else {
|
||||||
|
topOperation.isDisplayable = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
topOperation.isDisplayable = pages.contains(pageType)
|
||||||
|
}
|
||||||
|
|
||||||
/// When a detail page changes, check top alerts.
|
/// When a detail page changes, check top alerts.
|
||||||
@objc private func viewControllerChanged(notification: Notification) {
|
@objc private func viewControllerChanged(notification: Notification) {
|
||||||
reevaluteQueue()
|
reevaluteQueue()
|
||||||
|
|||||||
@ -15,6 +15,9 @@
|
|||||||
|
|
||||||
@property (readonly, getter=isPaused) BOOL paused;
|
@property (readonly, getter=isPaused) BOOL paused;
|
||||||
|
|
||||||
|
/// A bool for if this top alert can be displayed. It is only ready if true.
|
||||||
|
@property (nonatomic, getter=isDisplayable) BOOL displayable;
|
||||||
|
|
||||||
@property (nonatomic) BOOL reAddAfterCancel;
|
@property (nonatomic) BOOL reAddAfterCancel;
|
||||||
|
|
||||||
@property (nonnull, nonatomic, strong) MVMCoreTopAlertObject *topAlertObject;
|
@property (nonnull, nonatomic, strong) MVMCoreTopAlertObject *topAlertObject;
|
||||||
@ -30,7 +33,4 @@
|
|||||||
// Unpauses the operation, resuming any alert.
|
// Unpauses the operation, resuming any alert.
|
||||||
- (void)unpause;
|
- (void)unpause;
|
||||||
|
|
||||||
// NSOperationQueue uses KVO, this forces it to aknowledge changes
|
|
||||||
- (void)refreshReady;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
__block BOOL _paused;
|
__block BOOL _paused;
|
||||||
__block BOOL _displayed;
|
__block BOOL _displayed;
|
||||||
__block BOOL _animating;
|
__block BOOL _animating;
|
||||||
|
__block BOOL _displayable;
|
||||||
}
|
}
|
||||||
|
|
||||||
@property (readwrite, getter=isPaused) BOOL paused;
|
@property (readwrite, getter=isPaused) BOOL paused;
|
||||||
@ -26,6 +27,7 @@
|
|||||||
@property (strong, nonatomic) dispatch_queue_t pausedQueue;
|
@property (strong, nonatomic) dispatch_queue_t pausedQueue;
|
||||||
@property (strong, nonatomic) dispatch_queue_t displayedQueue;
|
@property (strong, nonatomic) dispatch_queue_t displayedQueue;
|
||||||
@property (strong, nonatomic) dispatch_queue_t animatingQueue;
|
@property (strong, nonatomic) dispatch_queue_t animatingQueue;
|
||||||
|
@property (strong, nonatomic) dispatch_queue_t displayableQueue;
|
||||||
|
|
||||||
@property (nonatomic, strong) dispatch_source_t timerSource;
|
@property (nonatomic, strong) dispatch_source_t timerSource;
|
||||||
|
|
||||||
@ -40,6 +42,8 @@
|
|||||||
self.pausedQueue = dispatch_queue_create("paused", DISPATCH_QUEUE_CONCURRENT);
|
self.pausedQueue = dispatch_queue_create("paused", DISPATCH_QUEUE_CONCURRENT);
|
||||||
self.displayedQueue = dispatch_queue_create("displayed", DISPATCH_QUEUE_CONCURRENT);
|
self.displayedQueue = dispatch_queue_create("displayed", DISPATCH_QUEUE_CONCURRENT);
|
||||||
self.animatingQueue = dispatch_queue_create("animating", DISPATCH_QUEUE_CONCURRENT);
|
self.animatingQueue = dispatch_queue_create("animating", DISPATCH_QUEUE_CONCURRENT);
|
||||||
|
self.displayableQueue = dispatch_queue_create("displayable", DISPATCH_QUEUE_CONCURRENT);
|
||||||
|
self.displayable = YES;
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
@ -109,25 +113,35 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the current page is supported for this top alert.
|
|
||||||
|
- (BOOL)isDisplayable {
|
||||||
|
__block BOOL isDisplayable;
|
||||||
|
dispatch_sync(self.displayableQueue, ^{
|
||||||
|
isDisplayable = self->_displayable;
|
||||||
|
});
|
||||||
|
return isDisplayable;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setDisplayable:(BOOL)displayable {
|
||||||
|
if (displayable != self.isDisplayable) {
|
||||||
|
BOOL isReady = [super isReady];
|
||||||
|
if (isReady) {
|
||||||
|
[self willChangeValueForKey:@"isReady"];
|
||||||
|
}
|
||||||
|
dispatch_barrier_async(self.displayableQueue, ^{
|
||||||
|
self->_displayable = displayable;
|
||||||
|
});
|
||||||
|
if (isReady) {
|
||||||
|
[self didChangeValueForKey:@"isReady"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (BOOL)isReady {
|
- (BOOL)isReady {
|
||||||
BOOL isReady = [super isReady];
|
if (self.isCancelled) {
|
||||||
if (self.isCancelled || self.isFinished) {
|
return [super isReady];
|
||||||
return isReady;
|
|
||||||
}
|
}
|
||||||
|
return [super isReady] && self.isDisplayable;
|
||||||
NSArray<NSString *> *pages = [self.topAlertObject.json array:@"pages"];
|
|
||||||
if (pages.count == 0) {
|
|
||||||
return isReady;
|
|
||||||
}
|
|
||||||
|
|
||||||
UIViewController *detailViewController = [[MVMCoreUISplitViewController mainSplitViewController] getCurrentDetailViewController];
|
|
||||||
if (![detailViewController conformsToProtocol:@protocol(MVMCoreViewControllerProtocol)]) {
|
|
||||||
return isReady;
|
|
||||||
}
|
|
||||||
|
|
||||||
NSString *pageType = ((UIViewController<MVMCoreViewControllerProtocol> *)detailViewController).pageType;
|
|
||||||
return isReady && [pages containsObject:pageType];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)main {
|
- (void)main {
|
||||||
@ -254,11 +268,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)refreshReady {
|
|
||||||
[self willChangeValueForKey:@"isReady"];
|
|
||||||
[self didChangeValueForKey:@"isReady"];
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - Delegate functions
|
#pragma mark - Delegate functions
|
||||||
|
|
||||||
- (void)topAlertViewBeginAnimation {
|
- (void)topAlertViewBeginAnimation {
|
||||||
@ -278,6 +287,7 @@
|
|||||||
copyObject.topAlertObject = self.topAlertObject;
|
copyObject.topAlertObject = self.topAlertObject;
|
||||||
copyObject.paused = self.paused;
|
copyObject.paused = self.paused;
|
||||||
copyObject.reAddAfterCancel = self.reAddAfterCancel;
|
copyObject.reAddAfterCancel = self.reAddAfterCancel;
|
||||||
|
copyObject.displayable = self.isDisplayable;
|
||||||
copyObject.queuePriority = self.queuePriority;
|
copyObject.queuePriority = self.queuePriority;
|
||||||
for (NSOperation *dependency in self.dependencies) {
|
for (NSOperation *dependency in self.dependencies) {
|
||||||
[copyObject addDependency:dependency];
|
[copyObject addDependency:dependency];
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user