I'm updating an old project of mine. I'm doing good progress and everything goes smooth.
Yesterday when I finished working everything was ok with my project, no errors, no warnings.
Suddenly, when today I started the project and without pressing a single key, I got 23 warnings at once. All of them are:
Implicit conversion loses integer precision: 'NSInteger' (aka 'long') to 'int'
Has somebody experienced something similar? why the hell was yesterday all OK and today I have sucha mess?
Edit. Here is some example:
- (IBAction)previousText:(UIBarButtonItem *)sender {
int i=[self.indexPathArray indexOfObject:[self indexPathForActiveText]];
if (i>0) {
[self moveRows:i-1];
}
}
Edit It turns out that (I don't know why) the simulator I was using was iPhone retina (64 bit). I changed back to iPhone 3.5 inches (32 bit) and all the warnings went away.
Now the thing is, how do I make it compatible for both devices?
Don't use primitive C-types like int/unsigned and instead use the Objective-C types like NSInteger/NSUInteger.
These warnings will then disappear as the type sizes change depending on architecture.
Things get more interesting when you use printf-like functions as you will need to conditionally compile the formatting string, depending on architecture; for example:
NSInteger i = 1;
#if __LP64__
NSLog(#"i is %ld", i);
#else
NSLog(#"i is %d", i);
#endif
However, better (when the formatting statement is non-trivial):
NSInteger i = 1;
NSLog(#"i is %ld", (long)i);
64bit warning.
NSInteger i=[self.indexPathArray indexOfObject:[self indexPathForActiveText]];
You probably updated your xcode. The latest turned on a lot of warnings for when you're compiling against say an iphone 5s or ipad air (x86_64)
Related
My MacOS Cocoa application displays a window of static text, meaning it should not be changed by the user, should not be first responder, etcetera. The only thing that happens to the text is that each word of it changes color (from "idleColor" to "highlightColor", and then back again) at a specific point in time. It is similar to a Karaoke display - individual words change color, and then change back, under program control, based on a list of timed events.
All of this works beautifully under MacOS 10.7 and 10.8. BUT, under 10.9, the text color does NOT change UNLESS I click in the window and continually move the cursor around, so I am manually highlighting (and un-highlighting) some of the text, continuously. If I do this, the regular words behave as intended. Essentially, it feels like the OS is refusing to update the window under program control, unless I am forcing it to update by manually performing something that requires the UI to respond.
The code that performs the color changes is as follows:
if (sEvent.attribute == HIGHLIGHT_ON) {
[sTextView setTextColor:highlightColor range: currentRange];
textIsLitUp = YES;
}
else {
[sTextView setTextColor:idleColor range: currentRange];
textIsLitUp = NO;
}
[sTextView setNeedsDisplay:YES];
(sTextView is a subclass of NSTextView.)
Now, if I comment out that last line, then I get the same, incorrect behavior under 10.7 and 10.8. In other words, under 10.9, the setNeedsDisplay method is not working, or not working the same way.
Does anyone have any ideas about working around this, or have any other light to shed on the problem? Or am I doing something terribly wrong? It is CRITICAL to the application that the changes to the textColor happen without latency!
EDITING MY QUESTION - to answer it:
Found the answer elsewhere here! I needed to call setNeedsDisplay on the main thread - it was in a secondary thread. The weird thing is that it always seemed to work fine under 10.7 and 10.8. It only broke under 10.9. So I just changed this:
[myTextField setNeedsDisplay:YES];
To this:
dispatch_async(dispatch_get_main_queue(), ^{[myTextField setNeedsDisplay:YES];});
…and it seem to have worked. Hope this helps someone else…
You don’t want to do any of the changing of AppKit objects in non-main threads—it’ll work sometimes, maybe even often, but then every once in a while it’ll crash, and you’ll wonder why. So:
[sTextView setTextColor:idleColor range: currentRange];
needs to be on the main thread, too.
I have very large graphic Mac app and now I receive a lot of the following messages in Console on 10.9 GM.
<Error>: Error: this application, or a library it uses, has passed an invalid numeric value (NaN, or not-a-number) to CoreGraphics API. This is a serious error and contributes to an overall degradation of system stability and reliability. This notice is a courtesy: please fix this problem. It will become a fatal error in an upcoming update.
I noticed that these messages appear in debugger after calling [NSApp nextEventMatchingMask: untilDate inMode: dequeue] but I think the reasons are in some other places. But I have too many places where I use Cocoa Graphics. I didn't receive this kind of message before 10.9.
How to detect where NaN is passing to CoreGraphics API?
After much digging around, I've found you can set a symbolic breakpoint on "CGPostError" in Xcode, and that will give you a stack trace.
The habit of creating lazy UIView's with a .zero frame played against me when doing it for a PDFView.
This
var pdfView = PDFView(frame: .zero)
will generate lots of the same logs from the question. The reason I used .zero, is because later I set up the view with constraints. This proved to be a problem. The solution was to use an arbitrary, non-zero frame when initializing the PDFView.
var pdfView = PDFView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
I was getting this error when I was foolishly retaining an NSPopover for future use.
It seems popover.showRelativeToRect(_:) is all you need to do, and then you can forget about it.
I found the problem. It's dividing by zero at some point that leads to NSAffineTransform with NaN elements in the matrix. For some reasons compiler and OS passed this situation before 10.9.
so you should get an exception at that point, so an exception breakpoint should work...
here are things to look out for...
you may have messed up a method signature... ie
-(float)myHeight
{
return 56.0;
}
gets messed up in a subclass
-(int)myHeight
{
return 42;
}
or you have some bad math(s) that emit a NaN...
there are a couple of ways to detect a NaN...
c99 introduced isnan()
also the ieee float trick of (f != f) will be true for NaN
I am working on a cross platform application that is over a decade old. The UI is by Qt and backend rendering is done with OpenGL. OpenGL contexts are managed in the back end, not by Qt.
I have recently added error checking and reporting for all OpenGL code in our app. Occasionally a situation arises where the first render initiated by Qt causes an "invalid drawable" error message in the terminal and all subsequent OpenGl calls fail with an "invalid framebuffer" error reported. These invalid drawable error messages have been treated as innocuous in the past, since before the user sees it the drawable eventually becomes valid and the scene is rendered correctly. However, with the new OpenGL error check/report it's not possible since there are large numbers of errors reported.
I would like to test if the drawable is valid. If it is not, it should return before the render starts. How can I verify that the drawable is valid?
MacBook Pro, OS X Mountain Lion (10.8.3), ati graphics card
I don't know at what API level you're working. I'm not sure it's possible to detect the problem after the fact. That is, if all you have is a context (perhaps implicit as the thread's current context) that failed to connect to its drawable.
I presume that Qt is using Cocoa under the hood. I further assume it has created an NSOpenGLContext and is invoking -setView: on it. You get that "invalid drawable" error if, at the time of that call, the view's window doesn't have a window device.
One common technique is to defer setting the context's view until the view has -drawRect: called on it, since at that point you're sure that the view has a window and the window has a device. (Although that ignores the possibility of forced drawing outside of the normal window display mechanism. For example, -cacheDisplayInRect:toBitmapImageRep:.)
If you just want to know at the point of the call to -setView: whether it's safe or not, I think you can rely on checking the value of [[view window] windowNumber]. The docs for -windowNumber say:
If the window doesn’t have a window device, the value returned will be equal to or less than 0.
Another approach is to prevent the problem rather than detect it. The strategy for that is basically to make sure the window has been shown and drawn before the call to -setView:. You may be able to force that by ordering it on-screen and invoking -display on it.
Ken Thomases post gave me the basic info I needed to find a workable solution. An additional conditional was needed. Here's what worked
//----------------------------------------------------------------------------
bool vtkCocoaRenderWindow::IsDrawable()
{
// you must initialize it first
// else it always evaluates false
this->Initialize();
// first check that window is valid
NSView *theView = (NSView*)this->GetWindowId();
bool win =[[theView window] windowNumber]>0;
// then check that the drawable is valid
NSOpenGLContext *context = (NSOpenGLContext *)this->GetContextId();
bool ok = [context view] != nil;
return win && ok;
}
I am pretty much an XCode beginner, and I therefore tried the, "Hello World" example given in the XCode documentation: Quick Start Guide: Tutorial: Using Xcode to Write “Hello, World!” for OS X.
I am using XCode 4.5.1 from whose documentation I took this example using OS 10.8.2. I followed the instructions; the example didn't work. It produced the window but not the "hello world" printing. The relevant code is:
- (void)drawRect:(NSRect)dirtyRect
{
// Drawing code here.
NSString *hello = #"Hello, World!";
NSPoint point =NSMakePoint(15, 75);
NSMutableDictionary *font_attributes = [[NSMutableDictionary alloc] init];
NSFont *font = [NSFont fontWithName:#"Futura-MediumItalic" size:42];
[font_attributes setObject:font forKey:NSFontAttributeName];
[hello drawAtPoint:point withAttributes:font_attributes];
[font_attributes release];
}
There are two notable things. The last line of this code gives an error:
release is unavailable: not available in automatic reference counting mode
So I commented this line out and ran the program. The window appeared, but no "Hello World". A long message appeared in the All Output, part of which read:
"/Users/me/Library/ScriptingAdditions/YouHelper.osax/Contents/MacOS/YouHelper: no matching architecture in universal wrapper
Hello: OpenScripting.framework - scripting addition "/Users/me/Library/ScriptingAdditions/YouHelper.osax" declares no loadable handlers."
Am I doing something dumb, or am I using the wrong example?
You have to remove [font_attributes release]; at the end of your code.
release, retain, alloc and dealloc are not available in ARC(Automatic Reference Counting). This is what the error says.
And for the second error you should remove anything that is referring to AppleScript and similar scripting addons for the app.
Without seeing you project it's difficult to find out what's wrong with it. My guess is: You forgot to specify the custom view's class in IB (Step 12 in "Design the User Interface").
Automatic indentation in my Xcode sometimes comes out wrong. I can't see any rhyme or reason to when it is correct and when it isn't. Here is a typical case where Xcode got it wrong. Selecting and asking Xcode to re-indent does not help. Of course I can fix it manually. But it would be much better to fix whatever is wrong with my Xcode.
Any successful experiences out there?
-(UIFont*) font {
UIFont* actual = self.actualFont;
if (actual) {
return actual;
}
WJStyleSheet* sheet = self.styleSheet;
UIFont* r = sheet.font;
return r;
}
Does code completion still work completely. Can you for example type self.actual and then hit CTRL + SPACE and get a coloured code completion suggestion with the class next to actualFont? If not then I think this is related to the code completion which can get corrupted in Xcode.
I could fix this using the following answer: https://stackoverflow.com/a/8165886/784318