Hello,

I'm trying to detect when an NSTextView has finished being loaded into its 
window in a situation where -viewDidMoveToWindow won't work - is there another 
way of doing this that I'm overlooking?

Here's the situation, and the reason -viewDidMoveToWindow won't work:

I've spent the last week debugging a nasty crashing bug that affected my page 
layout code in rare circumstances when it was loaded on project open 
(http://www.cocoabuilder.com/archive/cocoa/298810-tracking-exc-bad-access-when-zombies-don-work.html?q=exc_bad_access#298810
 - many thanks to those who helped!). It turned out there were a couple of 
issues involved, one to do with layout, and the other to do with the timing of 
the page layout view getting swapped into the window, which is what I'm trying 
to solve now. This is how things are currently set up:

When a project in my program is opened, a text view is created 
programmatically. The user can choose whether to view text in a single text 
view or in a multiple pages view. Thus, in my NSTextView subclass, I have 
overridden -viewDidMoveToWindow to send out a notification that tells listeners 
when the text view has finished being moved to a window. I have my controller 
listen for this notification, and when it detects that the text view has moved 
to a window, it restores the user's previous settings. One of these settings is 
whether to use a multiple page (i.e. multiple text container) set up, and if 
this is set to YES then the text view gets swapped out and replaced with the 
page layout view.

(The reason it's done like this, by the way, rather than just creating the page 
layout view instead of the text view programmatically in the first place, is 
that it turns out you cannot create a multiple text view and load it with text 
off-screen. If you do, when you move it on to the screen it will work but you 
get lots of drawing artefacts, such as the insertion point appearing in 
multiple places. I had a technical support request out with Apple on this, and 
it took a good while to work out that the fix was to ensure the page layout 
view was only created and laid out once everything had been moved to a window. 
Therefore I wait until the regular single text view - which isn't affected by 
such artefacts - is safely loaded into a window before trying to swap in the 
page layout view.)

However, the problem is that it turns out it's not safe to swap out a view from 
-viewDidMoveToWindow (which I suppose shouldn't come as a big surprise). I had 
assumed -viewDidMoveToWindow would be final, and that the view would have 
finished moving to the window and getting set up by the time this method is 
called, but it's not the case. -viewDidMoveToWindow seems to be called from the 
private NSView method _setWindow:. NSTextView overrides _setWindow: and calls 
another private method, -_requestUpdateOfDragTypeRegistration, *after* 
-viewDidMoveToWindow has been called. -_requestUpdateOfDragTypeRegistration in 
turn calls -performSelector:withObject:afterDelay: on self (with the selector 
-updateDragTypeRegistration).

Thus, if I swap out the text view in -viewDidMoveToWindow:, the text view still 
tries to finish the rest of the _setWindow: method afterwards, and ends up 
calling -performSelector:withObject:afterDelay: on self after it has been 
deallocated.

So, I'm trying to find a more final way of only setting up the page view after 
the window is on screen and everything necessary has been moved to that window, 
so that the text view has completely finished loading. Overriding _setWindow: 
and posting the notification at the end of that method works, but obviously 
that is a private method and if I want to get on the Mac App Store I'm going to 
need to avoid such solutions. I've also tried only posting the notification 
after a delay of 0, which works and avoids the crash, but is a little slow - 
you can see the original text view getting loaded on screen before being 
swapped for the multiple page view.

By this point, I've probably over-complicated everything and am missing 
something obvious, so I'd be grateful for any suggestions. (Obviously 
-awakeFromNib and -windowDidLoad come before anything is guaranteed to be on 
screen, otherwise I would have used those from the get-go.)

Many thanks and all the best,
Keith


      
_______________________________________________

Cocoa-dev mailing list ([email protected])

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 [email protected]

Reply via email to