Why does XCode show the wrong object address in the debugger window? - iphone

My application tested whether my selectedViewController was equal to my moreNavigationController.
if( self.tabBarController.moreNavigationController == self.tabBarController.selectedViewController )
{
// do something awesome.
}
else
{
NSLog(#"No match");
}
The expression always evaluated false, so I started debugging. I put a breakpoint in the code and hovered my pointer over 'self', which caused the yellow cascading popup where I could see the addresses of both Controllers. The addresses were the same in the popup, which must be incorrect since the if statement failed. I see the same result in the debugger window.
I added these logging statements later, which revealed that the objects had 2 different addresses.
NSLog([NSString stringWithFormat:#"%d",(self.tabBarController.moreNavigationController)] );
NSLog([NSString stringWithFormat:#"%d",(self.tabBarController.selectedViewController)] );
Why did the debugger window lie? Specifically, does anyone know what value it displays as its address, and why the controllers would show the same address?

I have had this exact same problem, and I'm 90% sure it's related to building for a 2.1 (or possibly 2.X) SDK while using the 3.0 dev tools. In my case, setting the target SDK for 3.0 fixed this issue.
Having your debugger essentially lie to you is frustrating ;)

I am seeing EXACTLY the same thing. Especially with floats. I switch to 3.1 target and it displays right. The question is, is the code really working correctly under 2.1 (an NSLog of the variables tells me it is).

Related

Xcode / Simulator iPhone messes up display

As you can see, the simulator misses text on some buttons. I also saw this same behavior following along on the TapCounter demo off of YouTube.
Another issue (not shown in the screenshot) is that if you press on any key on TapCounter, NSString stringWithFormat (see below)
- (IBAction)add {
count++;
number.text = [NSString stringWithFormat:#"%i", count];
}
The act of executing the stringWithFormat line nukes the formatting on the label and reverts it to default value.
I did make sure that the simulator size and development size are identical, as you canm see.
This question appears a few times on this site. The answer at this related question worked for me, once I was able to interpret the instructions. Including getting the crash and fixing it.
Later: it appears that the fix of turning off auto-layout is enough to get the 6.0 simulator working - you might like to try this first to see if all the other stuff is actually necessary...

all UISteppers in my iOS app have become disabled

My app uses UIStepper controls in a few different views. I released a minor update to the app that shouldn't affect these views at all, and I started getting reports that all the UISteppers in the app are now disabled. One user sent a screen shot, and the stepper control appears as if its enabled property were set to NO. However, there's no place in my code where I set this property at all, and the default is YES. I've searched my app for instances of the term "enabled" to make sure I'm not somehow disabling it accidentally, and I'm not.
I thought perhaps the default value for the enabled property changed between iOS versions, but the users who have reported this are running iOS 5.1.1, the same as my development devices. And I only started hearing about the problem with this app update.
Besides setting the enabled property, I found that the steppers will be disabled if the min and max values are set to the same value. I'm pretty sure this is not happening in my app. The values are hard-coded and passed to a setup method, and I haven't changed this code since many app versions ago.
Do you know any other reason why this would happen? I can't reproduce the problem myself, and it only affects some users, so it's difficult to troubleshoot.
Here's my code for creating the UISteppers, for what it's worth:
- (UIStepper *)makeStepperInput:(float )currentValue minValue:(float)minValue maxValue:(float)maxValue increment:(float)increment {
int stepperWidth = 94;
int stepperHeight = 27;
CGRect stepperFrame = CGRectMake(0, 0, stepperWidth, stepperHeight);
UIStepper *stepperInput = [[[UIStepper alloc] initWithFrame:stepperFrame] autorelease];
stepperInput.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
[stepperInput setValue:currentValue];
[stepperInput setMinimumValue:minValue];
[stepperInput setMaximumValue:maxValue];
[stepperInput setStepValue:stepValue];
[stepperInput setContinuous:NO];
NSLog(#"making stepper with values %f, %f, %f, %f (%i)", currentValue, minValue, maxValue, stepValue, stepperInput.enabled);
[stepperInput addTarget:self action:#selector(onChange:) forControlEvents:UIControlEventValueChanged];
return stepperInput;
}
UPDATE: I have a user who was willing to install a debug version with the NSLog line above. He sent me the console output and it shows that the min and max value of the stepper are correct (1 and 20 in one case) and that the enabled property is YES. Unfortunately, that eliminates both of my theories about what could be happening here...
Okay, here's what happened. The method posted above is a simplified version of my real method, which provides some branching for pre-iOS 5 devices. To help with pre-iOS 5 support, I was actually declaring stepperInput as a UIControl, and then returning something different on iOS versions that don't support UIStepper.
Now the interesting part. I rolled my project back and started looking at my build settings, and remembered that before my last release, Xcode gave me one of those alert messages about my build settings being out of date. I had clicked the button to allow Xcode to make all the recommended changes. This time, I performed one change at a time and tested my app after each change.
The first of the recommended changes was to "Upgrade Compiler configuration to LVVM". ("The compiler configuration is set to 'com.apple.compilers.llvmgcc42'. This will upgrade to 'Apple LLVM compiler 4.0', which is the recommended setting for iOS targets.") As soon as I made that change, the problem appeared on my test device. So it seems that the old compiler allowed me to set UIStepper properties on an object declared as a UIControl, while the new compiler did not. Indeed, when I changed my NSLog line above to output the actual values of the stepper, instead of the values passed into the method, they all returned 0. Having its min and max values both set to 0 is what made the stepper appear to be disabled.
I didn't think this affected all users because I couldn't reproduce it, but I was testing with the older build settings rather than the build settings used for the release. So now I'm thinking that this probably does affect all users, and only some users have noticed it.
Anyway, the solution is to reorganize my code so I can declare that UIStepper as a real UIStepper, since the newer compiler doesn't allow the kind of fudging I was doing before.

What causes "NSScanner: nil string argument"?

I got this message when I save data to core data.
NSScanner: nil string argument
I didn't use any NSScanner method. Where did it come from?
This is a bug? What should I do with it?
Thanks help, please.
From experience, I can say that -[NSDecimalNumber initWithString:] or +[NSDecimalNumber decimalNumberWithString:] with a nil string is one thing that causes that log message.
Set a breakpoint on -[NSScanner initWithString:] to start with; if you don't catch it that way, then break on the other ways you might create a scanner, like +scannerWithString: and -[NSConcreteScanner initWithString:]. That's how I flushed my unwanted log statement out.
FWIW, I had this message come out whilst building a core data app.
It was due to me rebuilding and running the app in the simulator, which effectively kills off your running process without going through any of your exit methods.
Depending on when / where you are saving your managed object context, you could be left with an incomplete managed object somewhere, then scanners which would expect to find values would have nothing when the app was relaunched and the half baked objects were returned from the store.
I have the same crash log NSScanner: nil string argument.
This is my sitution
Everything works fine on device.
Crash at dequeueReusableCellWithIdentifier only on simulator
I solved it by
Product->Clean Then rebuild.Every thing works fine for me. I not sure why this happened.
I had met this problem on iOS 9 and iOS 10 BUT iOS 11 work fine,I solved it by removing observer in dealloc where I had used KVO.
Such as:
- (void)dealloc {
[self.collectionView removeObserver:self forKeyPath:#"contentSize"];
}
I got this crash error but not about nil string issue.
My reason is that I use a cell in storyboard as dynamic but set Static Cells in the Attributes inspector. I changed that attribute to Dynamic Prototypes, solved the problem.

Eclipse - Blackberry SDK - Debugging on device: "details unavailable - not supported by VM"

I'm having a strange problem while debugging my Blackberry Application on a real device (BB Bold 9700). When I debug the same application within the BB emulator, the app runs fine, but when I run it on the real device, the app behaves differently (custom painting goes completely wrong). What's even worse is that my Eclipse environment seems to be unable to view live objects correctly while being at a break point (debug time).
I've added a screenshot to illustrate the strange behaviour:
As you can see, the app stops at the breakpoint within the IF statement, but the Variables pane says that the variable "methodName" equals null. Moreover, when I want to look at the variable "methodArguments" which is of type org.json.me.JSONArray, it says "details unavailable - not supported by VM".
Does anyone know what's going on here? My app works great on the emulator, but it's currently useless on the real device.
Thanks in advance!
I think I fixed it:
The problem was that I was laying out Fields on a manager that wasn't yet added to the viewstack.
What did the trick for me was overriding onDisplay() in the manager that contained the Fields that were displayed wrong:
protected void onDisplay()
{
//Make sure superclass is called
super.onDisplay();
/*You have to call "this.setDirty(true)" when you perform layout on a
*manager that isn't added to the viewstack. Then you can use
*"this.isDirty()" to determine whether you need to re-layout the fields
*when the manager becomes visible.*/
if(this.isDirty())
{
//I'm not sure if I need to use "invokeAndWait" and not "invokeLater"
UiApplication.getUiApplication().invokeAndWait(new Runnable()
{
public void run()
{
for (int i = 0; i < getFieldCount(); i++)
{
/*This (custom) function makes sure the Field gets its
*size and position*/
layoutItem(getField(i));
}
}
});
//Make sure you set "dirty" to false, to make sure this only happens once
this.setDirty(false);
}
}
If anyone has a better solution, I'd be glad to hear it (and maybe improve my app).
org.json.me.JSONArray, it says "details unavailable - not supported by VM".
the JSON related stuff is not available on device running 4.5 and 4.6 BB OS. Import it into the code.
Download it from here.
https://github.com/douglascrockford/JSON-java
it is available as Open Source and then use it into your applications.

What's the best way to log debug info in an iphone app?

Is there some standard way or has anyone written something that allows you to log a message and have it be displayed either in a small scrolling section on the iphone screen or in a separate window in the iphone simulator?
Update:
For noobs like me and don't know, use the NSLog methods as decribed below and make sure you select Run->Console to display the console.
Would still like to know if anyone has written a simple logger that displays on the iphone itself....
I don't have enough 'reputation' to add a direct comment for your posting but: don't forget to go to XCode->Preferences->Debugging->On Start: Choose Show Console & Debugger
You can of course choose just the Console or whatever, but you'll probably want the Debugger to. To use that, just click to the left of the line you want to break at. You can also toggle from 'Activate' to 'Deactivate' so you if you know that there are a bunch of breakpoints you don't need to hit in the beginning of your application set the debugging to Deactive (in the debugging window) and then, before you hit the UI element in your app you want to debug, toggle that same button to Activate so your breakpoints become active. Otherwise, you could of course just click Continue until you got to your section.
Also, on the NSLog, if you start to accumulate a bunch of log statements, and you need to 'find' one in particular, it helps to do: NSLog(#"\n\n\nMy statement\n\n\n); which will give a bunch of line breaks. Also, for the uninitiated:
NSLog(#"My int: %d my BOOL: %d", myInt, myBOOL);
NSLog(#"My object of any NSObject: %#", anObjectOfAnyKind);
NSLog(#"My float: %f",myFloat);
Hope all of this is helpful and sorry if I got off track with the debugging bit ;)
The Objective-C (more correct, really) method is
NSLog(#"message");
But the standard C method will work also
printf("message");
Use NSLog(#"Log message");
If your have an application that is crashing then your can ask the users you the crash log. The crash log contains information about what the application was doing when it crashed and the stack trace.
iPhone app log files are also stored on your users computer, and are copied across everytime they sync their iPhone. ( Note that DEVICE_NAME will be the same name of your iPhone in iTunes, and each log file will begin with the name of the app. )
Mac OS X : /Library/Logs/CrashReporter/MobileDevice//
Windows XP: C:\Documents and Settings\Application Data\Apple computer\Logs\CrashReporter\
Windows Vista: C:\Users\AppData\Roaming\Apple computer\Logs\CrashReporter\MobileDevice\
For Swift, it's simply
print("log msg")