What causes this error? "CALayer position contains NaN: [240 nan]" - iphone

I've seen this happen whenever i rotate a screen that has a UITableView on it. I've found out that it happens inbetween the willRotate and didRotate method calls in UIViewController My co-workers have seen it in other spots as well, usually around rotation. It hadnt started happening until very recently, and we're stumped as to how we should deal with it (google searches don't turn up the error message in its exact form). Has anyone else encountered this that knows what to do about it?

(Decided to take this out of comments and put it as an answer, since I think it's a darned good answer :)
Ha! I had an NaN calculation (div0), too. Key debugging aid: the message in question is output by NSLog(), so set a breakpoint on NSLog() and watch what the OS is doing at that time. For me, it was myUISlider.value = NaN.
To set breakpoint:
XCode 3.x
CMD-SHIFT-Y (debug window.)
Breakpoints button.
"Double-click for symbol"
Type in "NSLog" (no quotes.)
XCode 4.x
CMD-6 (breakpoints navigator.)
"+" to add breakpoint (lower left.)
Select ADD SYMBOLIC BREAKPOINT.
Symbol: NSLog
Confirm: Done.
XCode 5.x - 7.1 (at least)
(Same as 4.x, except breakpoints navigator is CMD-7, now.)
Run app, watch it break on NSLog, check the stack traces.

I've found the problem.
When you reset the frame of a tableview, it calls the delegate method tableView:heightForRowAtIndexPath: for each row in the table so it can recalculate its content size if it needs to. At that point, we do some special handling to return the height, and due to some bad assumptions in our code, we mistakenly returned NaN due to a divide by zero error (the variable we divide by was assumed to never be zero). Making sure that we do not divide by zero here fixed it.

I've spent a day trying to find the code that causes same problem and solved it within a minutes after enabling "break on exception" in Xcode. Check this tutorial to see how to enable it.

I had this problem when i was assumed that:
tableView:heightForHeaderInSection: returned an NSInteger, but it returns CGFloat...
changing:
-(NSInteger)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
to
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
fixed my issue.
Edit:
At some point I figured out how computers work below the C level, so I thought I would share it... (I will use an register names from x86_64 as I am most familiar with them, ARM would be slightly different but analogous)
int f(){
float someFloat=5.0f;
return someFloat;
}
results in converting the value of someFloat to an integer type then copying that to a particular register: %rax then calling the return instruction.
float f(){
float someFloat=5.0f;
return someFloat;
}
results in copying the value of someFloat from its current location to a particular register: %xmm0 then calling the return instruction.
So if you have the wrong prototype the calling code will expect the value to be in the wrong place, you will end up really returning a garbage value.

This error also cost me a long time.
At the end I found my colleague wrote something like this:
UIEdgeInsets a;
a.left = (...some calculation);
button.imageEdgeInsets = a;
And I rewrote these code like this and fix the issue:
UIEdgeInsets a;
a.left = (...some calculation);
a.top = 0;
a.bottom = 0;
a.right = 0;
button.imageEdgeInsets = a;
some value of UIEdgeInsets isn't initialised properly, and it sometimes turn into a NaN value, and crash the application.
More generally, you should check whether all values of C-style structs are initialised properly.

There is an another way to reproduce the issue: using insetBy(dx:dy:) on a too small rect

You can try this yourTableview?.bounces = false. It works for me.

Related

Objective-C Xcode: Tableview detailitem empty

I'm doing this tutorial (http://www.raywenderlich.com/1845/how-to-create-a-simple-iphone-app-tutorial-part-2) to get the hang of ios development, but now I'm stuck.
It's probably just a little thing, but when I get in my detailView's method 'setDetailItem', the newDetailItem variable is empty (see screenshot).
I have no idea why this is, but in the tutorial this seems to get automatically filled.
Why is it empty and how do I get the right detailItem?
I checked the tutorial and a sample code is provided by them.It works fine with the memory.It is a setter method which is called when you provide the value like this
DetailViewController *detailController =segue.destinationViewController;
ScaryBugDoc *bug = [self.bugs objectAtIndex:self.tableView.indexPathForSelectedRow.row];
detailController.detailItem = bug;
check weather you are passing in valid memory value (here bug).if you give it nil then yeah there may be no memory

Objective C: How does 7 - 1 = 3?

NSLog(#"Before: %d",currentArticle);
currentArticle--;
NSLog(#"SUBTRACT %d",currentArticle);
"currentArticle" is an integer. This is only being echoed once in my console. If I do not run this subtraction, the number "currentArticle" remains at 7.
This is being run in the main thread, and only run once per user interaction.
I have also tried
currentArticle = currentArticle - 1;
With the same result. Am I taking crazy pills?
Thanks!
Edit:
Declared as follows:
extern int *currentArticle;
And assigned later as:
currentArticle = 0;
I tried rewriting as this:
int *curArticle; // in my .h file
curArticle = 1;
And then I run the
curArticle--;
and it still decrements by two...
I have stepped through the code and ensured there are no other calls hitting this variable.. Thanks for the feedback so far, I will keep hacking away at it.
I concur with the comments above. I'd bet a dollar that your code looks like:
int *currentArticle = 7; // or something
currentArticle may not even be a pointer to an int, specifically, but it's very likely a pointer to some 4-byte type. The '--' and '++' operators, when applied to pointers, decrement or increment by the size of the type that's pointed to.
Things I think of: Threads (if it's a strange problem, there are threads)? Or is it called by an event (which is triggered more than once)?

Why can't I store a float value - it's always zero!

I have a view controller that is created by the app delegate - it's the first one shown in the app.
In its interface I declare
float lengthOfTime;
I also set it as a property:
#property (nonatomic) float lengthOfTime;
And in it's implemetation:
#synthesize lengthOfTime;
In the class viewDidLoad method, I set the value:
self.lengthOfTime = 3.0f;
However, after this, the value is always zero.
No errors, no compile warnings, nothing. Just zero.
The class is instantiated, it is showing in the view, so I'm pretty sure it's not a nil reference.
I've searched all over Google and can't figure it out.
What's going on?!?
:(
The property should be atomic I think. Just declare it as:
#property float lengthOfTime;
Updating primitives is an atomic operation.
I'm not sure if that will solve your problem or not.
The "non-atomic" keyword is for protection from multi-threading issues where one thread gets interrupted in the middle of changing it. You can only interrupt an operation if it takes more than one instruction to perform. Updating a single floating-point value is a one-instruction operation, and therefore cannot be interrupted.
It is possible that your view is reading the value before -viewDidLoad is called. I would try setting the variable in a method that is called before the view is initialized such as -awakeFromNib.
I fixed it and don't know how I did it. That's the worst. Now I don't know how to solve it if it happens again.
I thought it wasn't being initialized, but I removed the line and it still works.
I think I'm even more frustrated than before.

iPhone app running in Instruments fails with unrecognized selector

I have an app that appears to run without problems in normal use. The Clang Static Analyzer reports no problems either. When I try to run it in Instruments, it fails with an unrecognized selector exception.
The offending line is a simple property setter of the form:
self.bar = baz;
To figure out what's going on, I added an NSLog() call immediately above it:
NSLog(#"class = %# responds = %d", [self class], [self respondsToSelector:#selector(setBar:)]);
self.bar = baz;
On the emulator (without Instruments) and on a device, this shows exactly what I'd expect:
class = Foo responds = 1
When running under Instruments, I get:
class = Foo responds = 0
I'm stumped as to what could cause this. Perhaps a different memory location is getting tromped on when it's in the Instruments environment? Can anyone suggest how I might debug this?
If bar belongs to self, can't you do bar=baz; ?
Check your properties.
Perhaps to you need a cast on baz?
There's not enough information here to know what's going on, but then, if you knew what information to provide you'd probably have already fixed it. So. A few things to check:
Is the "self" pointer being swizzled in any way? Try printing out the value of self at various points just for sanity's sake
When your code runs in Instruments, is it running in a different mode? (32-bit vs. 64-bit, Garbage collected vs. Retain-Release, etc.) I'm not sure why any of those would have an effect, but if it's running in a different mode, that's something to look into.
Are you synthesizing the setter correctly? Or is it being provided dynamically (via Core Data, etc.)? If you manually specify a setBar: method, do you still get the error?

Parameter losing value when passed

I'm sure this is something simple but I've been staring at it for a bit now and I think all I need is a fresh pair of eyes to look at it, and since my cat doesn't have a whole lot of experience with iPhone programming I've turned to you.
I am passing a variable of type float from a class (UIView) to another class (UIViewController) right before the variable is passed it's value is correct but when it reaches the function it loses it's value, it's shown to be 0 or -2 and I'm not sure why. Like I said I'm sure it's something simple but I just need a fresh pair of eyes to look at it
Code is below
//inside UIView
-(void)UpdateFloat
{
myFloat = myFloat + 0.01;
}
-(void)RemoveView
{
//Function Call
[viewController myFunction:myFloat];
}
//Function
-(void)myFunction:(float)myFloat
{
[myView removeFromSuperview];
[self.view addSubview:myOtherView];
[myOtherView anotherFunction:myFloat];
}
the float gets updated by a timer and when the UIView makes the function call the value of the float is correct (usually about 15.67)
any help would be appreciated
Thank you in advance,
BWC
If your float really is a float, I bet there is something else is going on somewhere else that's manipulating that value, it's not the message send. Search for every occurrence of that variable name.
You'll see stuff like this happen when you accidentally do integer math on floats (which is really easy to do). Check and make sure your floats are floats and all the math is being done in floats and no int math is happening.
It's also possible that it is a scope related thing and you are instead getting a different myFloat, hard to tell without all the source available.
Well, I don't understand you, because you say you pass from UIView to UIViewController. But in your code, you first call an function in the UIViewController, which have to be [self myFunction:myFloat] by the way, and in that function you call your UIView.
Ok Guys,
I think I've figured out why the float isn't retaining it's value but the reason also baffles me.
when I'm calling the ViewControllers function in the UIView Xcode is showing the warning that there is no method and that methods without a matching signature will assume to return(id) and pass '...' as arguments
I understand what this warning means but what I don't understand is that I have the method declared in the header of my viewController
-(void)myFunction:(float)myFloat;
I also have another view that calls functions to the view controller and it's not displaying that warning...I'm pretty sure this is the reason the float isn't retaining it's value but I don't know why it can't see the method signature