From 7389f5bf457bd18c3a37c6184d01745d500b1c6c Mon Sep 17 00:00:00 2001 From: Maarten Billemont Date: Wed, 26 Jun 2013 20:23:02 -0400 Subject: [PATCH] Fix queue of observer/notification blocks. [FIXED] Make sure all notification and observer blocks that expect the main thread are scheduled on it. --- External/UbiquityStoreManager | 2 +- MasterPassword/ObjC/MPAppDelegate_Store.m | 33 +-- MasterPassword/ObjC/Mac/MPMacAppDelegate.m | 22 +- .../ObjC/Mac/MPPasswordWindowController.m | 40 +-- .../ObjC/iOS/MPElementListController.m | 3 +- .../ObjC/iOS/MPLogsViewController.m | 3 +- .../ObjC/iOS/MPMainViewController.m | 11 +- .../ObjC/iOS/MPUnlockViewController.m | 18 +- .../ObjC/iOS/MainStoryboard_iPhone.storyboard | 267 +++--------------- Press | 2 +- Site/2013-05/css/main.css | 118 ++++---- 11 files changed, 179 insertions(+), 340 deletions(-) diff --git a/External/UbiquityStoreManager b/External/UbiquityStoreManager index d6f71c56..59a0c1e8 160000 --- a/External/UbiquityStoreManager +++ b/External/UbiquityStoreManager @@ -1 +1 @@ -Subproject commit d6f71c56846e77c05bd876852ec0675fb6c755e3 +Subproject commit 59a0c1e8452ba1094fafdd1d8804a1edfe93347c diff --git a/MasterPassword/ObjC/MPAppDelegate_Store.m b/MasterPassword/ObjC/MPAppDelegate_Store.m index 4bcf97b3..121c8b8d 100644 --- a/MasterPassword/ObjC/MPAppDelegate_Store.m +++ b/MasterPassword/ObjC/MPAppDelegate_Store.m @@ -103,25 +103,22 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext, delegate:self]; #if TARGET_OS_IPHONE - [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillTerminateNotification - object:[UIApplication sharedApplication] queue:nil - usingBlock:^(NSNotification *note) { - [[self mainManagedObjectContext] saveToStore]; - }]; - [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillResignActiveNotification - object:[UIApplication sharedApplication] queue:nil - usingBlock:^(NSNotification *note) { - [[self mainManagedObjectContext] saveToStore]; - }]; + [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillTerminateNotification object:[UIApplication sharedApplication] + queue:[NSOperationQueue mainQueue] usingBlock: + ^(NSNotification *note) { + [[self mainManagedObjectContext] saveToStore]; + }]; + [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillResignActiveNotification object:[UIApplication sharedApplication] + queue:[NSOperationQueue mainQueue] usingBlock: + ^(NSNotification *note) { + [[self mainManagedObjectContext] saveToStore]; + }]; #else - [[NSNotificationCenter defaultCenter] addObserverForName:NSApplicationWillTerminateNotification - object:[NSApplication sharedApplication] queue:nil - usingBlock:^(NSNotification *note) { - NSManagedObjectContext *moc = self.mainManagedObjectContextIfReady; - [moc performBlockAndWait:^{ - [moc saveToStore]; - }]; - }]; + [[NSNotificationCenter defaultCenter] addObserverForName:NSApplicationWillTerminateNotification object:NSApp + queue:[NSOperationQueue mainQueue] usingBlock: + ^(NSNotification *note) { + [self.mainManagedObjectContextIfReady saveToStore]; + }]; #endif return storeManager; diff --git a/MasterPassword/ObjC/Mac/MPMacAppDelegate.m b/MasterPassword/ObjC/Mac/MPMacAppDelegate.m index 23e00005..18685cd8 100644 --- a/MasterPassword/ObjC/Mac/MPMacAppDelegate.m +++ b/MasterPassword/ObjC/Mac/MPMacAppDelegate.m @@ -232,13 +232,19 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven [MPConfig get].delegate = self; __weak id weakSelf = self; [self addObserverBlock:^(NSString *keyPath, id object, NSDictionary *change, void *context) { - [weakSelf updateMenuItems]; + dispatch_async(dispatch_get_main_queue(), ^{ + [weakSelf updateMenuItems]; + }); } forKeyPath:@"key" options:0 context:nil]; [self addObserverBlock:^(NSString *keyPath, id object, NSDictionary *change, void *context) { - [weakSelf updateMenuItems]; + dispatch_async(dispatch_get_main_queue(), ^{ + [weakSelf updateMenuItems]; + }); } forKeyPath:@"activeUser" options:0 context:nil]; [self addObserverBlock:^(NSString *keyPath, id object, NSDictionary *change, void *context) { - [weakSelf updateMenuItems]; + dispatch_async(dispatch_get_main_queue(), ^{ + [weakSelf updateMenuItems]; + }); } forKeyPath:@"storeManager.cloudAvailable" options:0 context:nil]; // Status item. @@ -249,16 +255,18 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven self.statusView.target = self; self.statusView.action = @selector(showMenu); - [[NSNotificationCenter defaultCenter] addObserverForName:USMStoreDidChangeNotification object:nil queue:nil usingBlock: + [[NSNotificationCenter defaultCenter] addObserverForName:USMStoreDidChangeNotification object:nil + queue:[NSOperationQueue mainQueue] usingBlock: ^(NSNotification *note) { [self updateUsers]; }]; - [[NSNotificationCenter defaultCenter] - addObserverForName:USMStoreDidImportChangesNotification object:nil queue:nil usingBlock: + [[NSNotificationCenter defaultCenter] addObserverForName:USMStoreDidImportChangesNotification object:nil + queue:[NSOperationQueue mainQueue] usingBlock: ^(NSNotification *note) { [self updateUsers]; }]; - [[NSNotificationCenter defaultCenter] addObserverForName:MPCheckConfigNotification object:nil queue:nil usingBlock: + [[NSNotificationCenter defaultCenter] addObserverForName:MPCheckConfigNotification object:nil + queue:[NSOperationQueue mainQueue] usingBlock: ^(NSNotification *note) { self.rememberPasswordItem.state = [[MPConfig get].rememberLogin boolValue]? NSOnState: NSOffState; self.savePasswordItem.state = [[MPMacAppDelegate get] activeUserForMainThread].saveKey? NSOnState: NSOffState; diff --git a/MasterPassword/ObjC/Mac/MPPasswordWindowController.m b/MasterPassword/ObjC/Mac/MPPasswordWindowController.m index 964d05db..3a0628a3 100644 --- a/MasterPassword/ObjC/Mac/MPPasswordWindowController.m +++ b/MasterPassword/ObjC/Mac/MPPasswordWindowController.m @@ -57,34 +57,38 @@ // @"their passwords to change. You'll need to update your profile for that site with the new password."]; // [moc saveToStore]; // }]; - [self ensureLoadedAndUnlockedOrCloseIfLoggedOut:YES]; + dispatch_async(dispatch_get_main_queue(), ^{ + [self ensureLoadedAndUnlockedOrCloseIfLoggedOut:YES]; + }); } forKeyPath:@"key" options:NSKeyValueObservingOptionInitial context:nil]; - [[NSNotificationCenter defaultCenter] - addObserverForName:NSWindowDidBecomeKeyNotification object:self.window queue:nil usingBlock:^(NSNotification *note) { + [[NSNotificationCenter defaultCenter] addObserverForName:NSWindowDidBecomeKeyNotification object:self.window + queue:[NSOperationQueue mainQueue] usingBlock: + ^(NSNotification *note) { [self ensureLoadedAndUnlockedOrCloseIfLoggedOut:NO]; [self.siteField selectText:nil]; }]; - [[NSNotificationCenter defaultCenter] - addObserverForName:NSWindowWillCloseNotification object:self.window queue:nil usingBlock:^(NSNotification *note) { - dispatch_async( dispatch_get_main_queue(), ^{ - NSWindow *sheet = [self.window attachedSheet]; - if (sheet) - [NSApp endSheet:sheet]; - - [NSApp hide:nil]; - self.closing = NO; - } ); - }]; - [[NSNotificationCenter defaultCenter] - addObserverForName:MPSignedOutNotification object:nil queue:nil usingBlock:^(NSNotification *note) { + [[NSNotificationCenter defaultCenter] addObserverForName:NSWindowWillCloseNotification object:self.window + queue:[NSOperationQueue mainQueue] usingBlock: + ^(NSNotification *note) { + NSWindow *sheet = [self.window attachedSheet]; + if (sheet) + [NSApp endSheet:sheet]; + + [NSApp hide:nil]; + self.closing = NO; + }]; + [[NSNotificationCenter defaultCenter] addObserverForName:MPSignedOutNotification object:nil + queue:[NSOperationQueue mainQueue] usingBlock: + ^(NSNotification *note) { _activeElementOID = nil; [self.siteField setStringValue:@""]; [self.typeField deselectItemAtIndex:[self.typeField indexOfSelectedItem]]; [self trySiteWithAction:NO]; [self ensureLoadedAndUnlockedOrCloseIfLoggedOut:YES]; }]; - [[NSNotificationCenter defaultCenter] - addObserverForName:USMStoreDidChangeNotification object:nil queue:nil usingBlock:^(NSNotification *note) { + [[NSNotificationCenter defaultCenter] addObserverForName:USMStoreDidChangeNotification object:nil + queue:[NSOperationQueue mainQueue] usingBlock: + ^(NSNotification *note) { [self ensureLoadedAndUnlockedOrCloseIfLoggedOut:NO]; }]; diff --git a/MasterPassword/ObjC/iOS/MPElementListController.m b/MasterPassword/ObjC/iOS/MPElementListController.m index 0c53eb7e..1e20d626 100644 --- a/MasterPassword/ObjC/iOS/MPElementListController.m +++ b/MasterPassword/ObjC/iOS/MPElementListController.m @@ -15,7 +15,8 @@ - (void)viewDidLoad { - [[NSNotificationCenter defaultCenter] addObserverForName:USMStoreDidChangeNotification object:nil queue:nil usingBlock: + [[NSNotificationCenter defaultCenter] addObserverForName:USMStoreDidChangeNotification object:nil + queue:[NSOperationQueue mainQueue] usingBlock: ^(NSNotification *note) { [self updateData]; }]; diff --git a/MasterPassword/ObjC/iOS/MPLogsViewController.m b/MasterPassword/ObjC/iOS/MPLogsViewController.m index 4158b8fa..2e145661 100644 --- a/MasterPassword/ObjC/iOS/MPLogsViewController.m +++ b/MasterPassword/ObjC/iOS/MPLogsViewController.m @@ -27,7 +27,8 @@ [super viewDidLoad]; - [[NSNotificationCenter defaultCenter] addObserverForName:NSUserDefaultsDidChangeNotification object:nil queue:nil usingBlock: + [[NSNotificationCenter defaultCenter] addObserverForName:NSUserDefaultsDidChangeNotification object:nil + queue:[NSOperationQueue mainQueue] usingBlock: ^(NSNotification *note) { self.levelControl.selectedSegmentIndex = [[MPiOSConfig get].traceMode boolValue]? 1: 0; }]; diff --git a/MasterPassword/ObjC/iOS/MPMainViewController.m b/MasterPassword/ObjC/iOS/MPMainViewController.m index e1b879c0..863d14e2 100644 --- a/MasterPassword/ObjC/iOS/MPMainViewController.m +++ b/MasterPassword/ObjC/iOS/MPMainViewController.m @@ -81,15 +81,17 @@ ^(NSNotification *note) { self.suppressOutdatedAlert = NO; }]; - [[NSNotificationCenter defaultCenter] addObserverForName:MPElementUpdatedNotification object:nil queue:nil usingBlock: - ^void(NSNotification *note) { + [[NSNotificationCenter defaultCenter] addObserverForName:MPElementUpdatedNotification object:nil + queue:[NSOperationQueue mainQueue] usingBlock: + ^(NSNotification *note) { MPElementEntity *activeElement = [self activeElementForMainThread]; if (activeElement.type & MPElementTypeClassStored && ![[activeElement.content description] length]) [self showToolTip:@"Tap to set a password." withIcon:self.toolTipEditIcon]; if (activeElement.requiresExplicitMigration) [self showToolTip:@"Password outdated. Tap to upgrade it." withIcon:nil]; }]; - [[NSNotificationCenter defaultCenter] addObserverForName:MPSignedOutNotification object:nil queue:nil usingBlock: + [[NSNotificationCenter defaultCenter] addObserverForName:MPSignedOutNotification object:nil + queue:[NSOperationQueue mainQueue] usingBlock: ^(NSNotification *note) { BOOL animated = [[note.userInfo objectForKey:@"animated"] boolValue]; @@ -107,7 +109,8 @@ [self.navigationController popToRootViewControllerAnimated:animated]; }]; }]; - [[NSNotificationCenter defaultCenter] addObserverForName:USMStoreDidChangeNotification object:nil queue:nil usingBlock: + [[NSNotificationCenter defaultCenter] addObserverForName:USMStoreDidChangeNotification object:nil + queue:[NSOperationQueue mainQueue] usingBlock: ^(NSNotification *note) { if (!self.activeElementForMainThread) [self didSelectElement:nil]; diff --git a/MasterPassword/ObjC/iOS/MPUnlockViewController.m b/MasterPassword/ObjC/iOS/MPUnlockViewController.m index f9c7df04..098b7995 100644 --- a/MasterPassword/ObjC/iOS/MPUnlockViewController.m +++ b/MasterPassword/ObjC/iOS/MPUnlockViewController.m @@ -170,20 +170,24 @@ [self initializeWordLabel:wordLabel]; } recurse:NO]; - [[NSNotificationCenter defaultCenter] addObserverForName:USMStoreDidChangeNotification object:nil queue:nil usingBlock: + [[NSNotificationCenter defaultCenter] addObserverForName:USMStoreDidChangeNotification object:nil + queue:[NSOperationQueue mainQueue] usingBlock: ^(NSNotification *note) { [self updateUsers]; }]; - [[NSNotificationCenter defaultCenter] addObserverForName:USMStoreDidImportChangesNotification object:nil queue:nil - usingBlock:^(NSNotification *note) { - [self updateUsers]; - }]; - [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillResignActiveNotification object:nil queue:nil usingBlock: + [[NSNotificationCenter defaultCenter] addObserverForName:USMStoreDidImportChangesNotification object:nil + queue:[NSOperationQueue mainQueue] usingBlock: + ^(NSNotification *note) { + [self updateUsers]; + }]; + [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillResignActiveNotification object:nil + queue:[NSOperationQueue mainQueue] usingBlock: ^(NSNotification *note) { [self emergencyCloseAnimated:NO]; self.uiContainer.alpha = 0; }]; - [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidBecomeActiveNotification object:nil queue:nil usingBlock: + [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidBecomeActiveNotification object:nil + queue:[NSOperationQueue mainQueue] usingBlock: ^(NSNotification *note) { [self updateLayoutAnimated:NO allowScroll:NO completion:nil]; [UIView animateWithDuration:1 animations:^{ diff --git a/MasterPassword/ObjC/iOS/MainStoryboard_iPhone.storyboard b/MasterPassword/ObjC/iOS/MainStoryboard_iPhone.storyboard index 94fe5514..7bdc81d2 100644 --- a/MasterPassword/ObjC/iOS/MainStoryboard_iPhone.storyboard +++ b/MasterPassword/ObjC/iOS/MainStoryboard_iPhone.storyboard @@ -1,7 +1,8 @@ - + - + + @@ -470,6 +471,7 @@ Your passwords will be AES-encrypted with your master password. + @@ -537,6 +539,7 @@ Your passwords will be AES-encrypted with your master password. + @@ -553,6 +556,7 @@ Your passwords will be AES-encrypted with your master password. + @@ -1048,6 +1052,7 @@ L4m3P4sSw0rD + @@ -1056,7 +1061,7 @@ L4m3P4sSw0rD - + @@ -1166,6 +1171,7 @@ L4m3P4sSw0rD + @@ -1448,7 +1454,7 @@ You can use the words in the background for inspiration in finding a memorable m - + - + @@ -2251,6 +2264,7 @@ If you set a custom password, it will be encrypted before it is saved to the clo + @@ -2282,10 +2296,10 @@ If you set a custom password, it will be encrypted before it is saved to the clo - + - + @@ -2296,6 +2310,7 @@ If you set a custom password, it will be encrypted before it is saved to the clo + @@ -2349,6 +2364,7 @@ If you set a custom password, it will be encrypted before it is saved to the clo + @@ -2361,11 +2377,11 @@ If you set a custom password, it will be encrypted before it is saved to the clo - + - + - + @@ -2466,6 +2482,7 @@ You can make passwords for anything, like email addresses, sites or real-world t + @@ -2488,11 +2505,11 @@ You can make passwords for anything, like email addresses, sites or real-world t - + - + @@ -2632,7 +2649,7 @@ You can make passwords for anything, like email addresses, sites or real-world t - + - + @@ -2787,6 +2804,7 @@ You can make passwords for anything, like email addresses, sites or real-world t + @@ -2823,11 +2841,11 @@ You can make passwords for anything, like email addresses, sites or real-world t - + - + @@ -2855,13 +2873,14 @@ However, it means that anyone who finds your device unlocked can do the same. - + + @@ -2916,204 +2935,6 @@ However, it means that anyone who finds your device unlocked can do the same. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -3121,6 +2942,6 @@ However, it means that anyone who finds your device unlocked can do the same. - + \ No newline at end of file diff --git a/Press b/Press index a4c772e4..9e6fa54f 160000 --- a/Press +++ b/Press @@ -1 +1 @@ -Subproject commit a4c772e43cdf8eadb75e09625f44112549ccd07d +Subproject commit 9e6fa54f624890944dd817eb345f348cc1196dc7 diff --git a/Site/2013-05/css/main.css b/Site/2013-05/css/main.css index 67a4c3e0..ddeba0e9 100644 --- a/Site/2013-05/css/main.css +++ b/Site/2013-05/css/main.css @@ -12,17 +12,17 @@ nav { } nav { - opacity: 0.85; + opacity: 0.85; } h1, h2, h3, h4 { - margin-top: 1em; + margin-top: 1em; } .content { - padding-top: 100px; - width: 940px; - margin: auto; + padding-top: 100px; + width: 940px; + margin: auto; } .box { display: inline-block; @@ -34,109 +34,109 @@ h1, h2, h3, h4 { } .thumb { - clear: both; - border-bottom: 2px ridge white; - margin-bottom: 4em; + clear: both; + border-bottom: 2px ridge white; + margin-bottom: 4em; } .thumb .pull-right { - margin-left: 5ex; + margin-left: 5ex; } .thumb .pull-left { - margin-right: 5ex; + margin-right: 5ex; } .column { - display: inline-block; - margin: 0 2em; - vertical-align: top; + display: inline-block; + margin: 0 2em; + vertical-align: top; } .navbar .nav .img { - padding: 4px; + padding: 4px; } .navbar .nav .img img { - display: block; - height: 32px; + display: block; + height: 32px; } header { - position: relative; - overflow: hidden; + position: relative; + overflow: hidden; - color: white; - background: black; - text-shadow: black 0 1px 50px; - box-shadow: 0 1px 5px #000; + color: white; + background: black; + text-shadow: black 0 1px 50px; + box-shadow: 0 1px 5px #000; } header .container { - position: relative; - width: 100%; - height: 100%; - z-index: 1; + position: relative; + width: 100%; + height: 100%; + z-index: 1; - background: radial-gradient(70% 50% at 30% 50%, rgba(0,0,0,0.3) 50%, rgba(0,0,0,0.8) 100%); + background: radial-gradient(70% 50% at 30% 50%, rgba(0,0,0,0.3) 50%, rgba(0,0,0,0.8) 100%); } header .background { - position: absolute; - width: 100%; - height: 100%; + position: absolute; + width: 100%; + height: 100%; } #app header { - height: 80%; + height: 80%; } #app header .background { - background: url('../img/shot-laptop-standing-iphone-angled-flipped.png') center center; + background: url('../img/shot-laptop-standing-iphone-angled-flipped.png') center center; background-size: cover; } #algorithm header { - height: 40%; - - background: #272727; + height: 40%; + + background: #272727; } #algorithm header .background { - width: 940px; - height: auto; - left: 50%; - top: -10%; - margin-left: -470px; + width: 940px; + height: auto; + left: 50%; + top: -10%; + margin-left: -470px; } #algorithm header .container { - background: radial-gradient(50% 50% at 50% 30%, rgba(0,0,0,0.3) 50%, rgba(0,0,0,0.8) 100%); + background: radial-gradient(50% 50% at 50% 30%, rgba(0,0,0,0.3) 50%, rgba(0,0,0,0.8) 100%); } header .content { - position: absolute; - bottom: 5px; - left: 50%; - margin-left: -470px; + position: absolute; + bottom: 5px; + left: 50%; + margin-left: -470px; - text-align: right; + text-align: right; - /*background: linear-gradient(to bottom, rgba(0,0,0,0) 85%, rgba(0,0,0,0.7) 85%);*/ - /*background: black url("../img/shot-laptop-leaning-iphone.png") center top / cover no-repeat;*/ + /*background: linear-gradient(to bottom, rgba(0,0,0,0) 85%, rgba(0,0,0,0.7) 85%);*/ + /*background: black url("../img/shot-laptop-leaning-iphone.png") center top / cover no-repeat;*/ } header h1 { - font-size: 4em; + font-size: 4em; } header h2 { - font-size: 2em; - font-weight: normal; + font-size: 2em; + font-weight: normal; } footer { - overflow: hidden; - text-align: center; + overflow: hidden; + text-align: center; } footer h1 { - background: #EEE; + background: #EEE; font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; - font-size: 170%; - font-weight: 100; + font-size: 170%; + font-weight: 100; } footer .content { - margin: 1em auto; - padding: 0; + margin: 1em auto; + padding: 0; } footer .column { - text-align: left; + text-align: left; }