summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorjrg@chromium.org <jrg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-25 21:49:44 +0000
committerjrg@chromium.org <jrg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-25 21:49:44 +0000
commit4ef4e0c8c772d15ed016c3e2380cf874f045250b (patch)
treec5ac574e1eb8ff93d1c1d15a455af7ef00005c30 /chrome
parent3d2315b49da77d975f832019e729b4d7fc6d8cfa (diff)
downloadchromium_src-4ef4e0c8c772d15ed016c3e2380cf874f045250b.zip
chromium_src-4ef4e0c8c772d15ed016c3e2380cf874f045250b.tar.gz
chromium_src-4ef4e0c8c772d15ed016c3e2380cf874f045250b.tar.bz2
Try to fix top crasher.
The problem is timing related so I am unable to write a unit test which proves this fixes things. The essence of the change is to make sure we don't send messages to objects which no longer exist by clearing the delegate pointer in objects we own before we go away (where "we" is an object). The delegate pattern does not get retained, which gives certain objects to hold dangling pointers. BUG=53205 http://crbug.com/53205 Review URL: http://codereview.chromium.org/3158031 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@57399 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/cocoa/bookmark_bar_controller.mm7
-rw-r--r--chrome/browser/cocoa/bookmark_bar_folder_controller.mm14
-rw-r--r--chrome/browser/cocoa/bookmark_button_cell.mm4
3 files changed, 22 insertions, 3 deletions
diff --git a/chrome/browser/cocoa/bookmark_bar_controller.mm b/chrome/browser/cocoa/bookmark_bar_controller.mm
index 245f599..89d4273 100644
--- a/chrome/browser/cocoa/bookmark_bar_controller.mm
+++ b/chrome/browser/cocoa/bookmark_bar_controller.mm
@@ -1373,6 +1373,7 @@ const NSTimeInterval kBookmarkBarAnimationDuration = 0.12;
if (NSMaxX([button frame]) < maxViewX)
break;
[buttons_ removeLastObject];
+ [button setDelegate:nil];
[button removeFromSuperview];
--displayedButtonCount_;
}
@@ -1440,7 +1441,10 @@ const NSTimeInterval kBookmarkBarAnimationDuration = 0.12;
// Delete all buttons (bookmarks, chevron, "other bookmarks") from the
// bookmark bar; reset knowledge of bookmarks.
- (void)clearBookmarkBar {
- [buttons_ makeObjectsPerformSelector:@selector(removeFromSuperview)];
+ for (BookmarkButton* button in buttons_.get()) {
+ [button setDelegate:nil];
+ [button removeFromSuperview];
+ }
[buttons_ removeAllObjects];
[self clearMenuTagMap];
displayedButtonCount_ = 0;
@@ -2379,6 +2383,7 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) {
poofPoint = [oldButton convertPoint:poofPoint toView:nil];
poofPoint = [[oldButton window] convertBaseToScreen:poofPoint];
NSRect oldFrame = [oldButton frame];
+ [oldButton setDelegate:nil];
[oldButton removeFromSuperview];
if (animate && !ignoreAnimations_ && [self isVisible])
NSShowAnimationEffect(NSAnimationEffectDisappearingItemDefault, poofPoint,
diff --git a/chrome/browser/cocoa/bookmark_bar_folder_controller.mm b/chrome/browser/cocoa/bookmark_bar_folder_controller.mm
index 34cfd20..26e498a 100644
--- a/chrome/browser/cocoa/bookmark_bar_folder_controller.mm
+++ b/chrome/browser/cocoa/bookmark_bar_folder_controller.mm
@@ -146,6 +146,14 @@ const CGFloat kScrollWindowVerticalMargin = 0.0;
[self removeScrollTracking];
[self endScroll];
[hoverState_ draggingExited];
+
+ // Delegate pattern does not retain; make sure pointers to us are removed.
+ for (BookmarkButton* button in buttons_.get()) {
+ [button setDelegate:nil];
+ [button setTarget:nil];
+ [button setAction:nil];
+ }
+
// Note: we don't need to
// [NSObject cancelPreviousPerformRequestsWithTarget:self];
// Because all of our performSelector: calls use withDelay: which
@@ -175,8 +183,10 @@ const CGFloat kScrollWindowVerticalMargin = 0.0;
- (void)reconfigureMenu {
[NSObject cancelPreviousPerformRequestsWithTarget:self];
- for (BookmarkButton* button in buttons_.get())
+ for (BookmarkButton* button in buttons_.get()) {
+ [button setDelegate:nil];
[button removeFromSuperview];
+ }
[buttons_ removeAllObjects];
[self configureWindow];
}
@@ -1222,6 +1232,7 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) {
if (parentNode->GetChildCount() == 1) {
BookmarkButton* emptyButton = [buttons_ lastObject];
newButtonFrame = [emptyButton frame];
+ [emptyButton setDelegate:nil];
[emptyButton removeFromSuperview];
[buttons_ removeLastObject];
}
@@ -1349,6 +1360,7 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) {
buttonThatMouseIsIn_ = nil;
}
+ [oldButton setDelegate:nil];
[oldButton removeFromSuperview];
if (animate && !ignoreAnimations_)
NSShowAnimationEffect(NSAnimationEffectDisappearingItemDefault, poofPoint,
diff --git a/chrome/browser/cocoa/bookmark_button_cell.mm b/chrome/browser/cocoa/bookmark_button_cell.mm
index 48b7a7d..cc03904 100644
--- a/chrome/browser/cocoa/bookmark_button_cell.mm
+++ b/chrome/browser/cocoa/bookmark_button_cell.mm
@@ -180,6 +180,8 @@
// To implement "hover open a bookmark button to open the folder"
// which feels like menus, we override NSButtonCell's mouseEntered:
// and mouseExited:, then and pass them along to our owning control.
+// Note: as verified in a debugger, mouseEntered: does NOT increase
+// the retainCount of the cell or its owning control.
- (void)mouseEntered:(NSEvent*)event {
[super mouseEntered:event];
[[self controlView] mouseEntered:event];
@@ -187,8 +189,8 @@
// See comment above mouseEntered:, above.
- (void)mouseExited:(NSEvent*)event {
- [super mouseExited:event];
[[self controlView] mouseExited:event];
+ [super mouseExited:event];
}
- (void)setDrawFolderArrow:(BOOL)draw {