NSOutlineView: reloadData and crashes in reloadData

Apple, Cocoa, General

A note to NSOutlineView Cocoa programmers: It has never been safe to call reloadData while an outlineView is doing a reloadData. What the heck does that mean? Well, if you call reloadData, a whole bunch of delegate/datasource methods will be called, such as outlineView:numberOfChildrenOfItem:, outlineView:isItemExpandable:, etc. Well, if in those delegate methods you accidentally call reloadData again, bad things can happen. Specifically, you will probably get a crash in NSOutlineView. More often than not, this is done by an accidental side effect, but it is something to be aware of. On Leopard, I will make NSOutlineView more resilient to this case, and not crash. On Tiger, you can fix it yourself, if you think it is (or may) affect you. Here is the general recipe:

1. Subclass NSOutlineView, and add an iVar that looks like:

   BOOL _isReloading;

2. Override reloadData and make it look something like this:

- (void)reloadData {
    if (!_isReloading) {
       _isReloading = YES;
       [super reloadData];
       _isReloading = NO;
   } else {
       [self performSelector:@selector(reloadData) withObject:nil afterDelay:0];
   }
}
Previous Post
no_thumbnail
New blog layout
Next Post
no_thumbnail
Mail tip of the day
0 0 votes
Article Rating
Subscribe
Notify of
guest
6 Comments
Inline Feedbacks
View all comments
Matthew Sachs

The big code sample looks fine, although perhaps the font is a bit small. Did you mean to have “BOOL _isReloading;” and “reloadData” in the “general recipe” inside tt ?

Sören Kuklau

I use code instead of tt (same thing, except with specific semantic meaning), but for what it’s worth, my CSS regarding code and pre looks like this:

code, pre {
font: 1.25em ‘Courier New’, Courier, Fixed, Monospace;
}

code, pre {
overflow: auto;
overflow-x: hidden;
}

pre {
display: block;
}

The first block increases the font size to ensure (in my case, anyhow) anti-aliasing is on; matter of taste, I guess, but I’ve gotten so used to Quartz’s smooth text rendering that I find non-anti-aliased text on a web page horrible to look at. (Text editors are a different matter entirely.)

The second block creates horizontal and/or vertical scroll bars as needed. This prevents the rest of the layout from breaking, because the scroll bars are specific to the very element. overflow-x isn’t actually part of CSS (though don’t quote me on this; CSS 3 might be adding it); that part is just there to work around an IE 6 bug, so you might as well leave it out.

The third block is probably self-explanatory.

You could just replace “code” with “tt”, or apply the style to both.

Hope that helps.

Michael

Corbin,

I’m a bit new to Cocoa programming and I have a question about NSOutlineViews. I’ve been scouring the web for a simple solution and I feel that I just have to ask this question myself now. What I would like is a static “source list” style outline view. Just to clarify my usage of the term static, the data in the outline view is not user-editable. Would you recommend using a plist to populate this outline view or should it be hardcoded? Do you have any tutorials for doing this? I am also confused about the root object in an outline view — should this be a dictionary or array that maintains the top-level rows?

As an Amazon Associate I earn from qualifying purchases.

(c) 2008-2021 Corbin Dunn

Privacy Policy

Subscribe to RSS feeds for entries.

79 queries. 0.402 seconds.

Log in