Corbin's Treehouse - Corbin Dunn, Santa Cruz, CA
Plug Bug
Treehouse
Photography
Videos
Projects
Unicycling
About

NSOutlineView: reloadData and crashes in reloadData


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];
   }
}


6 Responses to “NSOutlineView: reloadData and crashes in reloadData”

  1. corbin says:

    i realize i need to fix my pre and tt HTML layout. Any suggestions?

  2. Matthew Sachs says:

    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 ?

  3. Sören Kuklau says:

    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.

  4. corbin says:

    Super, looks MUCH better. Thanks all!!

  5. Michael says:

    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?

  6. corbin says:

    Michael — the best thing to do is to get a good starter book, like “Ccoc programming for mac os ” by hillegass. it is easiest to fill a table/outline with static data from a plist or something; that way, you can easily and dynamically change it, if required. or, use bindings and NSTreeController


(c) 2008-2017 Corbin Dunn

Corbin's Treehouse is powered by WordPress. Made on a Mac.

Subscribe to RSS feeds for entries and comments.

38 queries. 0.422 seconds.