On 22-Oct-09, at 2:24 AM, Quincey Morris wrote:

1. Yes, there's a defect in the NSDocumentController design which makes it awkward to pass an initial state to a new document without having to re-implement everything that NSDocumentController does. Awkward but not impossible or even difficult. So let's just get over it and move on.

Now that I've heard someone knowledgeable say that, I am happy to move on. I figured I was just using the framework incorrectly, since usually "fighting with the framework" indicates that (which indicates how good Apple's designs usually are!)

2. My second suggestion *in no way* depends on knowing what any method of NSDocumentController actually does, except that I consulted the documentation for 'newDocument:' to guide me in choosing which method to override. If that bugs you, override 'newDocument:' too, to make it do what the documentation says it currently does, and you're future-proofed until and unless 'openUntitledDocumentAndDisplay:error:' is deprecated.

Given that they deprecated a wave of these methods in 10.4 (including the predecessor to openUntitledDocumentAndDisplay:error:), that does worry me a bit. The architecture seems like a work in progress, which makes me feel I ought to tread especially carefully.

My first suggestion depends on knowing that the type passed to the new document instance will be provided by 'defaultType'. It's conceivable but extremely unlikely that this is ever going to change, but if that bothers you, use the second suggestion.

Both your fixes still strike me as hacks, and having just spent some weekends updating old apps that were bitten by changes that I thought at the time were "conceivable but extremely unlikely," I am now more wary of such evaluations than I used to be. But your suggestions do seem fairly safe.

Your existing code is, in a sense, more dependent on the current implementation details of NSDocumentController, because you're trying to do what the documentation says that NSDocumentController does.

Yes, this is exactly what bothers me about it, and is why I've been looking for a better solution.

3. The only ways my second suggestion (and, for all practical purposes, my first suggestion) could fail are (a) if documents were being created on multiple threads, which can't happen because NSDocumentController isn't thread safe, or (b) if 'openUntitledDocumentAndDisplay:error:' could possibly get called recursively, which it doesn't. If you're worried about that, then go ahead and use your current implementation, which is perfectly viable even if it makes you uncomfortable.

Well, I was worried about a scenario, for example, where multiple documents were getting created at once, and that was done in an interleaved fashion such that your suggested code would end up setting the type into the special ivar/global multiple times, then getting the last set type out of the ivar/global multiple times, thus making many documents of the last type set, rather than one document each of each one type set. But the more I ponder it the less likely that seems to actually happen, so I won't worry about it.

Huh? You *are* getting advice from somebody who knows how this architecture is intended to be used, both from having implemented "a document like this", and from having carefully absorbed *extensive* discussions on this list of how the NSError** output parameter is intended to be used.

Please don't be so easily offended. Your original reply did not indicate you had ever implemented such a scheme; it sounded like a tossed-off guess. Your wording "I don't understand why you think you can't..." made it sound like you felt there was no particular problem with the design of the framework, which made me suspicious of your answer; you seemed to just be saying "Why is there a problem, it's easy to hack your way around it," which is an attitude that is not terribly helpful when trying to understand the design of a framework and how best to use it. Your acknowledgement in this reply that there is indeed a defect in the architecture is much more useful. Your answer to the NSError question ("you're not returning an error object when you return nil at the end of the method") was unhelpful since adding a return of an NSError just changed the behavior of the code to a different, equally incorrect behavior; it took a more useful tip from a different poster to point me to the fact that a *particular* NSError needed to be returned, which was not mentioned in any of the documentation that I was looking at. I state these things not to be critical (not trying to start a flamewar here!), but to explain to you why I asked the list for advice from "somebody who knows how this architecture was intended to be used" and someone who "has actually implemented a document like this". So. Thanks for your replies, and I hope I've caused no lasting offense.

Read this:

http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/ErrorHandlingCocoa/CreateCustomizeNSError/CreateCustomizeNSError.html#/ /apple_ref/doc/uid/TP40001806-CH204-BAJIIGCC

and note particularly:

Note: Cocoa methods that indirectly return error objects in the Cocoa error domain are guaranteed to return such objects if the method indicates failure by directly returning nil or NO. With such methods, you should always check if the return value is nil or NO before attempting to do anything with the NSError object.

NSDocumentController methods play by these specific rules, so your overrides must do so too. Returning the "user cancelled" error is a special-case refinement of the technique that permits the (ultimate) suppression of the error alert. (The same technique is useful in cases where there really is an error but you want to display the alert yourself, but you want to prevent the NSDocumentController from complaining a second time.) It's not really well documented, but -- I hope you noticed -- you got the answer for free just by asking the question.

OK, very good to know. As I noted in an earlier post, I was misled by the NSError documentation that says:

In general, a method should signal an error condition by—for example— returning NO or nil rather than by the simple presence of an error object. The method can then optionally return an NSError object by reference, in order to further describe the error.

Thanks for the ref to the better doc; I will read that, and if it seems appropriate, will file a doc bug on the item that misled me.

As for "I hope you noticed -- you got the answer for free just by asking the question", yes, of course I appreciate the list's helpfulness, and your helpfulness specifically, and I think I'm careful to thank people. There's no need to be snippy. I've posted hundreds of replies to this list and other cocoa-related lists helping people out myself, although that was many years ago now, since I took a multi-year break from coding recently. I'm sure there are old- timers around who remember me.

  So, thank you for your help.  Let's move on.

Ben Haller
Stick Software

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to