Re: NSAlert runModal in outlineView:acceptDrop crashes with may not be invoked inside of transaction begin/commit pair
Re: NSAlert runModal in outlineView:acceptDrop crashes with may not be invoked inside of transaction begin/commit pair
- Subject: Re: NSAlert runModal in outlineView:acceptDrop crashes with may not be invoked inside of transaction begin/commit pair
- From: Rob Petrovec via Cocoa-dev <email@hidden>
- Date: Sat, 31 Oct 2020 09:40:40 -0600
PLEASE PLEASE PLEASE don’t put up a modal dialog in the middle of a drag. All
drags are done on the main thread. This includes calls to NSDraggingSource,
NSDraggingDestination, NSFilePromiseProvider, NSFilePromiseReceiver methods and
drag methods from NSTableView/NSOutlineVIew & NSCollectionView. In some cases,
when the drag is between two apps, the other app involved in the drag may be
waiting for a response and is therefor blocked until your method returns. If
your implementation of these drag methods takes too long then both your app and
the other app involved can SPOD. To avoid this, try to perform any operations
that can take some time, like reading/writing to disk, asynchronously off the
main thread. If that is not an option (e.g. bringing up modal dialogs),
performing the operation after the drag method has returned will work too. You
can use methods like [self performSelector: … afterDelay: 0] to achieve this.
However, this will prevent the other app in the drag from SPOD’ing, your app
may still SPOD. So take that into consideration when choosing a technique to
fix this.
As for the problem you are asking about, the transactions its talking about
sound like CoreAnimation transactions dealing with drawing. I wouldn’t expect
the outline view drag call to be inside of one of those unless you are
overriding something to add one.
—Rob
> On Oct 31, 2020, at 6:24 AM, Michael Kloske via Cocoa-dev
> <email@hidden> wrote:
>
> Hello,
>
> I have an OutlineView. Whenever I drag and drop a child item within the
> Outline-View my application crashes when I open do an "NSAlert runModal" like
> in the code below:
>
> - (BOOL)outlineView:(NSOutlineView *)outlineView acceptDrop:(id <
> NSDraggingInfo >)info item:(id)item childIndex:(NSInteger)index
> {
> ...
> 1 if(needToAskUser)
> {
> 2 NSAlert *alert = [[NSAlert alloc] init];
> 3 // .. set some texts and buttons in alert
> 4 [alert runModal];
> }
> }
>
> In line 4 the app crashes with the following uncaught exception:
> [General] -[NSAlert runModal] may not be invoked inside of transaction
> begin/commit pair, or inside of transaction commit (usually this means it was
> invoked inside of a view's -drawRect: method.)
>
> I have a tree like this:
> Top Level 1
> - Child Item A
> - Child Item B
> Top Level 2
> - Child Item C
> ...
>
> The problem occurs only, when I drag one of the Child Items within the same
> view. It does not matter whether I move Child Item A below Child Item B or if
> I move it to another Top Level item, for example below Child Item C.
>
> Moving the block into a call to dispatch_async(dispatch_get_main_queue(), ^{
> }); did also not help.
>
> Has anyone any idea what the problem is?
> Best regards,
> Michael Kloske
>
> _______________________________________________
>
> Cocoa-dev mailing list (email@hidden)
>
> 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:
>
> This email sent to email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden