I'm using an NSOutlineView with the function
- (BOOL)outlineView:(NSOutlineView *)outlineView
isGroupItem:(id)item
defined so it gives the group row GUI look. When I add a root item, it works fine. When I add an item to root's child array and expand it, it works fine. If I contract the item though, the following error is logged:
[NSCFTimer copyWithZone:]: unrecognized selector sent to instance
I also get an EXC_BAD_ACCESS error if the app window is deactivated by switching to another app. I used the debugger to try to find where I might have made an error in one of my functions, but the stack trace only shows functions I did not create (RunCurrentEventLoopInMode, CFRunLoopRunSpecific, handleWindowNeedsDisplay, etc.) Does anyone have any idea where my error(s) might be?
Sounds like an object is dying prematurely. You get the “unrecognized selector sent to instance” exception when a new object is allocated later with the same pointer and then something tries to send the old object a message (in the example shown, the reincarnation is an NSTimer and the message something tried to send the previous object was copyWithZone:). You get an EXC_BAD_ACCESS crash when the object is simply garbage memory.
Debug this by running your app under Instruments with the Zombies instrument enabled. The object will, instead of dying, become a zombie object. When something tries to send a zombie a message, the zombie will moan (figuratively speaking), which will show up in Instruments's timeline as a flag. You can click a button in that flag to view the history of the object, including all of its retentions and releases.
Related
I am using an NSCollectionView where each NSCollectionViewItem uses a QLPreviewView to get a rendering of a file's content.
(This is an attempt at a file browser for images and other previewable files.)
Initially, this works fine.
However, once collection items are getting re-used, I get an assertion error (both in 10.13 and 10.14):
[QL] Assertion failure (unreachable code) - [… MyPreviewView activated … doc:[QLPreviewDocument …]] is already activated
Apparently, before I can re-use a NSCollectionViewItem, the previously used QLPreviewItem needs to be set to inactive state somehow. How do I do that?
I've tried to send the close message to the QLPreviewView instance but that doesn't make a difference.
I also do not get a dealloc call on my QLPreviewView subclass, which suggests that the object is still referenced by something else, possibly the QLPreviewDocument, which then gets confused about the change of state.
I have made a demo project available on github: https://github.com/tempelmann/NSCollectionViewWithQLPreview
To test: Run it, then scroll down. When reaching items 50 to 60, the assertion will be triggered.
The fix is to set QLPrewiewView's shouldCloseWithWindow property to NO.
This, I suspect, tells the controller behind the scenes not to attach itself to higher level structures, i.e. tells it to remain self-sufficient.
So, adding this line to the code that sets up a new MyPrewiewView object in the sample code's ViewController.m file prevents the error:
qlView.shouldCloseWithWindow = NO;
I`ve got a Cocoa UI app that needs to update its main window as fast as the rest of its UI event loop permits, so I implemented the main updater function via a CFRunLoopObserver. I also have an application-modal alert box and a context menu.
So, my problem is that when I have both an alert and a context menu on the screen, the updater gets stuck, presumably due to excess number of nested run loops above the one it has been attached to back at the start. Surprisingly, I can alleviate the issue by duplicating the observer, and it keeps running — one instance only, randomly chosen from the two existing when the «blocking» nested loop starts. When it ends (a menu item gets chosen, an alert exceeds its timeout or is dismissed manually — whatever), things get back to normal, and the blocked observer regains the ability to run.
Now the question: is there a way to have a single observer that gets executed no matter how deep the run loop stack is?
Sidestepping the runloop issue, have you looked at CVDisplayLink?
You set one up using CVDisplayLinkCreateWithActiveCGDisplays(), and then attach a callback using CVDisplayLinkSetOutputCallback(). It'll ask for data at the refresh rate of the display, so you'll be getting the callback as fast as you need.
I have a TreeView that allows users to change the labels. To do this I have a handler for the TVN_ENDLABELEDIT notification that reads the TVITEM from the NMTVDISPINFO structure and sends the TVM_SETITEM message.
All of this works fine EXCEPT in one particular case: when for the sake of debbuging I interrupt the execution of the handler BEFORE returning with 0 from the notification.
What happens in this case is that if another notification arrives before the handler returns with 0, i.e., before I'm done debbuging it, the TreeView will crash the application because it will call a rutine at a null pointer.
This means that the TreeView somehow trusts the handler from finishing before other event gets processed.
Has anyone experienced this kind of behavior? I think the OS should be a little bit more robust; shouldn't it?
I hope I can explain this problem decently well!
I'm trying to implement a ReWire audio device as a Delphi .dll. If you don't know what ReWire is, don't worry about it. What's important is that my code compiles into a .dll, and I get calls from the ReWire system into my .dll to open up a display, check if the display is opened, and close it again.
When I get the call to launch, I do the following:
if not Assigned(form) then
form := TMyForm.Create(nil);
form.Show;
where form is a global variable inside of my Delphi library (maybe a problem?). I have hooked up MyForm's OnCreate event to do some interesting things like prepare an array of stuff I want to work with.
So far everything's good. My form has a little button in it that opens up a TOpenDialog. I find that as soon as that dialog closes, somehow the OnCreate event is firing again in my form!
I have checked that OnDestroy is not being called, so I have no idea why OnCreate is getting called again.
Unfortunately I'm not really sure what information is relevant, but here's the call stack the first time around (when the form is first set up):
As expected, ReWire is making a call into my .dll to Launch the Panel application, so I create my form. Great, things are looking good.
Then inside my form, I open up a little dialog, select a file, and do some operations. Out of left field, OnCreate is called again, and here's the call stack that time:
It's a crazy party of calls! Reaper (at the bottom) is the ReWire host I'm using to test my application, but I have no idea what's going on inside that stack trace because none of it is my code. Suddenly the event just gets called when I don't think it should, because OnDestroy wasn't even called.
The only other important thing I can think of is that if I print out the address of the Sender, it's different each time, so it's somehow getting Created again or something, but I've checked that I only call the MyForm.Create once.
Any ideas as to how this type of thing could happen?
In the first stack trace, the OnCreate call is preceded by a call to TCustomForm.Create(), which is correct behavior. In the second stack trace, the OnCreate call is preceded by a call to TObject.Create() instead, which is not correct behavior. That leads me to think that something in your button OnClick event handler is either constructing an object with a bad VMT, or is otherwise corrupting memory in general and causing a bad jump into code that just happens to be occupied by your TForm class. Either way, double check your OnClick logic for bugs.
Check on (any)where you are setting the form variable to nil. It may be that it's being set to nil without freeing the form it's pointing to, and so next time your launch code is called it's creating another instance of the form.
A simple 10.6 Cocoa app I wrote that basically draws a regular window with some buttons and text has been spewing hundreds of console log messages:
<Error>: CGContextSetCompositeOperation: invalid context 0x0
I do not directly call drawRect: and always use setNeedsDisplay:YES when I need to refresh.
Interestingly, this error does not happen on all machines, I'd say about 50% get the error. However, the program works fine in either case!
Anyone got any clue as to what this error means, where it's stemming from, and more importantly, how can I suppress/get rid of it?
Thanks
Try setting a breakpoint on CGPostError. If you can break on the logging, you can hopefully figure out what's going on.
You shouldn't be looking to just suppress it. It means context creation is failing (thus NULL gets passed for some context parameter), and that's not good.