Re: CFRunLoopObserver causes crash on NSView drag.
Re: CFRunLoopObserver causes crash on NSView drag.
- Subject: Re: CFRunLoopObserver causes crash on NSView drag.
- From: "Mr. Gecko" <email@hidden>
- Date: Sat, 22 Oct 2011 19:43:25 -0500
According to instruments, this seems to be working fine. Thanks.
On Oct 22, 2011, at 12:42 PM, Jean-Daniel Dupas wrote:
> I also encounter this annoying issue, and also try something like that, but as you can see, it does not works.
>
> I workaround this issue by periodically posting application defined event that trigger an event loop, and make the framework drain the autorelease pool.
>
> Somewhere in my application initialization:
>
> [NSTimer scheduledTimerWithTimeInterval:60 target:self selector:@selector(drainAutoreleasePool:) userInfo:nil repeats:YES];
>
>
> And the draining method:
>
> - (void)drainAutoreleasePool:(NSTimer *)aTimer {
> // We hope it does not have side effects (other than draining the pool)
> NSEvent *evt = [NSEvent otherEventWithType:NSApplicationDefined location:NSMakePoint(0, 0)
> modifierFlags:0 timestamp:CFAbsoluteTimeGetCurrent()
> windowNumber:0 context:nil subtype:0 data1:0 data2:0];
> [NSApp postEvent:evt atStart:NO];
> }
>
>
>
> Le 22 oct. 2011 à 15:53, Mr. Gecko a écrit :
>
>> Hello, I have a problem with 10.7 where when you drag files to a view which accepts files, it'll crash because of a leak of some sort. This is triggered by my CFRunLoopObserver which I've written because operations which is done in the background never had the autorelease pool drained until the UI was brought up and my application's UI was hardly ever brought up.
>>
>> Let me explain the setup. First is my run loop observer.
>>
>> static NSAutoreleasePool *pool = nil;
>>
>> void runloop(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info) {
>> if (activity & kCFRunLoopEntry) {
>> if (pool!=nil) [pool drain];
>> pool = [NSAutoreleasePool new];
>> } else if (activity & kCFRunLoopExit) {
>> [pool drain];
>> pool = nil;
>> }
>> }
>>
>> CFRunLoopObserverContext context = {0, self, NULL, NULL, NULL};
>> CFRunLoopObserverRef observer = CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopEntry | kCFRunLoopExit, YES, 0, runloop, &context);
>> CFRunLoopAddObserver(CFRunLoopGetCurrent(), observer, kCFRunLoopDefaultMode);
>>
>> This is what I used to get around the memory never being released while the UI was not shown. Because my application deals in files and has watchers for files, whenever a watcher found a file and read it, that file would stay in the ram until you bought up the UI. I know I could of added my own NSAutoReleasePool for that part, but that also means other parts of my code will have to add that as well as well as some notifications which was way more work/code than wanted.
>>
>> Now my NSView is in a NSStatusItem which will be used for when someone drags to that menu in the menubar, it'll allow them to drop the file and have the file be uploaded. My NSView registers for files with the following line.
>>
>> [self registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType]];
>>
>> Even if I just do that and do not listen for drag operations, it'll crash because of my loop observer creating and draining that autorelease pool. All I can say is that all of this was working in 10.6 and now is broken in 10.7.
>>
>> Here is the crash stack so you can see what I'm talking about.
>> Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
>> 0 libobjc.A.dylib 0x00007fff946d800b (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 385
>> 1 com.apple.CoreFoundation 0x00007fff92527f75 _CFAutoreleasePoolPop + 37
>> 2 com.apple.Foundation 0x00007fff8ecfa057 -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 275
>> 3 com.apple.Foundation 0x00007fff8ed7dc0a -[NSRunLoop(NSRunLoop) runUntilDate:] + 66
>> 4 com.apple.AppKit 0x00007fff8e4a2523 NSCoreDragTrackingProc + 3477
>> 5 com.apple.HIServices 0x00007fff94279b0d DoTrackingMessage + 357
>> 6 com.apple.HIServices 0x00007fff9427b42c CoreDragMessageHandler + 461
>> 7 com.apple.CoreFoundation 0x00007fff925ebbb9 __CFMessagePortPerform + 729
>> 8 com.apple.CoreFoundation 0x00007fff924f911c __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 44
>> 9 com.apple.CoreFoundation 0x00007fff924f8e4b __CFRunLoopDoSource1 + 155
>> 10 com.apple.CoreFoundation 0x00007fff9252f587 __CFRunLoopRun + 1895
>> 11 com.apple.CoreFoundation 0x00007fff9252eae6 CFRunLoopRunSpecific + 230
>> 12 com.apple.HIToolbox 0x00007fff9843c3d3 RunCurrentEventLoopInMode + 277
>> 13 com.apple.HIToolbox 0x00007fff9844363d ReceiveNextEventCommon + 355
>> 14 com.apple.HIToolbox 0x00007fff984434ca BlockUntilNextEventMatchingListInMode + 62
>> 15 com.apple.AppKit 0x00007fff8e0ca3f1 _DPSNextEvent + 659
>> 16 com.apple.AppKit 0x00007fff8e0c9cf5 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 135
>> 17 com.apple.AppKit 0x00007fff8e0c662d -[NSApplication run] + 470
>> 18 com.apple.AppKit 0x00007fff8e34580c NSApplicationMain + 867
>>
>> Some of my options are:
>> 1. Forget about the memory usage and remove my runloop observer.
>> 2. Find a new way to prevent this memory issue from happening.
>> 3. Have apple fix Lion.
>> 4. Do whatever you suggest I do.
>>
>> If you can think of how I can fix this issue, please let me know. If you need a test subject, I am willing to point you to my source code._______________________________________________
>>
>> 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
>
> -- Jean-Daniel
>
>
>
>
_______________________________________________
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