I'd like to move from NSLogging all over the place to using breakpoints for logging where the performance hit doesn't preclude it.
I know I can just po an object with a Debugger Command action, and I know I can just log any string by choosign the Log Message action.
And I think I should be able to combine both by choosing Log Message and entering something like SomeText giving context for object description: #(const char *)[[anObject description] UTF8String]#. Unfortunately, this doesn't seem to work, and always gives me what I assume to be the pointer to the description string.
What am I doing wrong?
It's kinda tricky but I think that this will work. Set the breakpoint Action as a debugger command. Then use this text as the action:
po (NSString *) [#"Some text describing: " stringByAppendingString:(NSString *)[anObject description]]
You must always be very careful to cast return types when working in the debugger. Both with GDB and LLDB.
I like your idea of using breakpoints to avoid the performance hit, but this also means that your logs will only be printed when connected to a debugger. While NSLogs will buffer their output to the system log, viewable from the Organizer (Devices) in Xcode.
(Edit: I missed the question's point and it's not an answer)
I think it's best to use DebugLog. It's a macro, and you can disable it easily (it's on when you def-ine DEBUG in your debug builds and is off when you don't define it). So, there's no performance degradation (quite the contrary).
Simply replace
NSLog(#"Hello, World!");
with
DebugLog(#"Hello, World!");
And instead of
19/4/12 8:55:52.949 PM Dictionary: Hello, World!
You'll get:
BetterDictionary.m:737 Hello, World!
(it shows which file and even which line has logged it)
Which is infinitely more interesting. undefine DEBUG for your production build and DebugLog won't be called at all.
And don't forget to #import 'DebugLog.h'.
Related
- (BOOL)mySetting
{
return [myObject returnYes];
}
For a method such as the above, is it possible to add a breakpoint with a debugger command so that the -mySetting method automatically returns a different value (such as NO) when the breakpoint is enabled?
I'm looking for an option where the debugger doesn't have to interrupt execution of the app, (a.k.a. has "Automatically continue after evaluating actions" turned on).
While zylenv's answer will work, it'll require you to create a temporary variable and recompile/launch.
The proper way to do this would be to use lldb's thread return command. It is used like this:
A good blog post explaining its usage (and a bunch of other cool LLDB stuff) is here.
You can use lldb debugger to change the return value of the method.
Just did like below.
I have a method on one of my ViewController's that is called by one of its view's and delivered some value. It then sends out a message to a manager object with some information about the VC's state.
- (void)elementXChangedWithValue:(float)value {
ParameterManager * pMan = [ParameterManager sharedInstance];
[pMan updateParameter:self.elementX.parameter value:value];
}
In debugging, it was important for me to inspect what the .SomeElement.parameter state was so I could know what was getting lost in translation by the time I get to my ParameterManager.
Unfortunately, although Self is definitely non-nil and accessible the debugger shows scant information about the class making quick and practical glancing of the value difficult. (i will sometimes invoke "po" command in the debugger command line, however).
Not sure if it helps but this project is running heavy with the Objective-C/Swift interoperability although the ViewController is a fully Objective-C class.
Here is an image of what I am getting in the debugger. The drop-down arrow shows nothing but empty.
The debugger isn't perfect and sometimes you just cant see what is in certain areas, such as self. What does always work is NSLog's placed in code though, so if all else fails, add one of those in at the right place to print out the object you wish to know about.
The debugger may show more info after you make it execute these commands:
expr #import UIKit;
expr #import Foundation;
This loads the whole UIKit and Foundation symbols in the debugger at runtime, you only need to execute it once per debug session.
You can automate this with a user-defined breakpoint that'll be triggered every time your application starts in the debugger.
Source : http://furbo.org/2015/05/11/an-import-ant-change-in-xcode/
I have:
AFHTTPRequestOperation* operation;
...
if ([operation.request.URL.path isEqualToString:somePath])
{
...
}
When I print it out I get:
(lldb) po operation.request.URL.path
/users/12345678/data/something
But when I hover over the variable path, the Xcode popover shows:
users/12345678/data/something
Why?
ps: Shown URLs are purely fictional :-) But it really does happen here and now.
To err on the side of caution, yes, do what Jason said and file a bug, and we will look at it.
On the other hand, be aware that in general, "po" works by running an API on your object provided by the framework vendors. Hovering in Xcode works by invoking the LLDB data formatters provided by the LLDB team.
There is no promise that the two will agree in the way they choose to represent objects (cfr. po #[#1,#2,#3] with p #[#1,#2,#3] to see this very clearly)
This sounds like a bug. If you can make a small self-contained repro example project, I'd encourage you to file a bug report at http://bugreport.apple.com/
Is it possible to access the properties of objects in xCode console?
If I try the following I get an error that he property doesn't exist.
po someObject.someprop
If I don't breakpoint the code and run the app it works fine so I know someObject.someprop exists. I don't think I have the grasp on xCode console yet? What I loved about Flex/Flash development is that I could set a break point and in the console window or variables view I could traverse every structure down to the ends of the earth.
I could see SomeDicionary[key].someArray[1].someObject.prop and it would show me the value. Is this not possible in xCode console or is there a trick to get to it?
You'll actually have to use the bracket syntax notation:
po [someObject someprop]
The debugger is sometimes very finnicky about syntax. This is filled with all sorts of helpful tips for debugging in XCode.
Just a side note, variables/properties declared in the implementation file (*.m) instead of the header file (*.h) can sometimes be invisible to the debugger variable list display depending on if the breakpoint is in that class's code, because of scope. Not necessarily required here, but useful to know seeing as how it is kind of relevant.
in a method that is accessed three times I want to write something to the log.
NSLog(#"%#", [response responseString]);
But there is nothing in the log. The log windows is completely white. Normally when I start an application there is always some stuff that shows up in the log but now it is totally empty.
How can I fix this?
Perhaps a really silly thing, but in the top right-corner of the console you should see this:
Check that the middle segment or right segment is selected.
NSString *responseString = [response responseString];
NSLog(#"%#", responseString);
set a breakpoint on the first line and debug the application to see if its coming in this code in the first place. If it is, hover over responseString and it will tell you whether it is nil or not.
When Console isn't behaving nicely for me (which happens sometimes when I'm doing driver level stuff or multi-threaded apps), a much more reliable thing to do is something like:
- (void) printToLog: (NSString *) aFormattedStringToPrint
{
// don't forget to remove an older copy of this file before
// your app finishes launching
FILE * aFile = fopen( "/tmp/debuggingoutput.txt", "a");
if(aFile)
{
fprintf(aFile, "%s", [aFormattedStringToPrint UTF8String];
fflush(aFile);
fclose(aFile);
}
}
(you can define a macro like LOGTHIS which might toggle between NSLog and the above more direct and to the point code)
And then you can "tail -f /tmp/debuggingoutput.txt" in your Terminal window while debugging and if nothing appears there, then you know your debugging lines aren't getting hit.
Today I have been frustrated with a similar problem. When the console is activated, only the variables pane is showing. No sign of the console pane. After finding Debug Area Help via right clicking in the variable pane, i could see that it is meant to sit next to it on the right.
The key for me was to Hide the Utilities panel. For me, the little buttons shown in Luke's answer above would not appear until hiding and unhiding the Utilites panel.