How could I view the value of [fetchedResultsController sectionIndexTitles] in the debugger without change the code?
return [fetchedResultsController sectionIndexTitles];
Currently, I use to trick of add an tempory variable s and then use "print the descriptions of 's'" command. But this method requires me change the code so it is not convenient.
NSArray *s= [fetchedResultsController sectionIndexTitles];
return s;
Similar, it would be very helpful to be able to see the value of [a method1] in following statement:
[b [a method1]]
Do use breakpoints ... Add breakpoint to your return line, right click on breakpoint, edit breakpoint and now you have two options ...
Add Action Debugger Command ...
expr (void)NSLog( #"%#", [fetchedResultsController sectionIndexTitles] );
... or Log Message Action in a similar way and turn on Automatically continue after evaluating.
What it does?
Every time you hit your line with breakpoint, your application is paused, breakpoint actions are processed and as you did turn on Automatically continue after evaluating, your program continues when these breakpoint actions are processed. This is the way how to log, inspect, ..., without modifying your code.
I found the trick:
After the breakpoint is hit, Simply type following command in the LLDB would do the job:
po [self.fetchedResultsController sectionIndexTitles]
Where po is an abbreviation for expression -o -- used to print the object description of the value resulting from the expression.
The return value is visible in Xcode debugger, immediately after returning from a function call (i.e. immediately after hitting the the "step out" button). See below screenshot for example:
Related
I have a function name declared as follows in OBjective C :
- (void)placeViews:(CGSize)screenSize;
In my viewDidLoad i call this function, and I want to put a breakpoint when it is called as such:
[self placeViews:size]
So in LLDB I am entering the following breakpoint command:
breakpoint set --selector placeViews:screenSize
But the LLDB is unable to resolve the breakpoint
However, when I only use "placeViews:" as the selector it finds the selector and adds the breakpoint.
What I don't get is why it finds the selector when I use "placeViews:", but it doesn't find it when i used the entire method name "placeViews:screenSize".
Why is that?
So what happens when I have multiple methods like another one such as "placeViews:screenSize:oneMoreThing" and I want to set a breakpoint only on this method, how can LLDB distinguish between "placeViews:screenSize" and "placeViews:screenSize:oneMoreThing" ?
thank you!
-Malena
placeViews:screenSize is not the selector name, the selector is just "placeViews:". The selector name does not include the variable name that is passed to the message that that selector indicates (screenSize in your case.)
That actually makes sense if you think about it, because users have to provide the "placeViews:" part of the selector when they call the method, but "screenSize" has no part of how they call it. Also, it is NOT an error to use screenSize in your #interface and a completely different name in the #implementation. So it really shouldn't be part of the name the runtime conses up for the message.
You can verify this, for instance run this in Terminal
$ otool -o | grep placeViews
name 0x100000f56 placeViews:
No mention of screenSize.
I am new Objective C development and i am having trouble with my workflow to send a message. In order to invoke a method a java i would type the following:
obj
// .. i am thinking about what to do... call a method!
obj.
// autocompletion pops up
obj.someMethod()
The workflow in XCode currently is not so convenient for me. Currently if often looks like this:
obj
// .. i am thinking about what to do... send a message!
obj //damn i need to have the bracket at the beginning
// and jumping to the beginning of the line with cmd+arrow ignores indentation!
[obj // now i need the cursor at the end of the line
[obj someMessage //now i have to insert the bracket myself :-(
[obj someMessage]
This gets even worse if i want to chain messages like [[obj someMessage] someOtherMessage].
I know that the workflow is better if i start with a bracket, but often i don't realize until typing that i need a message instead of a property (and that would not help with chaining either). Are there any shortcuts to make my life easier, e.g. wrap a line with brackets?
I hope i was able to express my problem in an understandable fashion. :-)
Xcode inserts the opening bracket when you add the closing bracket (| is cursor in my example).
Class|
// I am thinking about what to do... send a message!
Class alloc|
// now lets add the closing bracket
Class alloc]|
// opening bracket is inserted (cursor remains at end)
[Class alloc]|
// now I want to init as well
[Class alloc] init|
// and add closing bracket
[Class alloc] init]|
// opening bracket is inserted (cursor remains at end)
[[Class alloc] init]|
// done. let's just add the semi-colon
[[Class alloc] init];|
I have a UIWebView in which I set content offset at some point:
myWebView.scrollView.contentOffset = CGPointZero;
It turns out afterwards that this view is scrolled to the bottom of its content. How can I figure out which part of code sets that offset? I miss data breakpoints and watchpoints on it. But how can i do it in actual Xcode?
In Xcode 4.5, in the locals window, you can turn out objects to see the member ivars, right-click/control-click on the ivar of interest and hit "Watch " and anything that modifies that ivar in that object will stop execution. Alternatively, you can add a watchpoint from the debugger console like this,
(lldb) watch set variable myWebView.scrollView.contentOffset
or
(lldb) w s v myWebView.scrollView.contentOffset
(shortest unique command name is always valid in command line lldb)
I have see this in sample objective c code before, but can't find it now and all the searches come back with irrelivent results.
I want to write debug messages to the Xcode output window. What's the command to do that? Basically like System.Diagnostics.Debug.WriteLine for C#.
NSLog(#"Your message here");
...should do it.
To include data from variables you can use string formatting, e.g:
NSLog(#"Value of string is %#", myNSString);
There are a bunch of different string format specifiers, you can look at them here: https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html
You are looking for NSLog. Calling
NSLog(#"Message");
will print Message on the console.
See here for more info about how to use string formatters to print the values of variables like in the examples below:
NSLog(#"This is a string: #", aString);
NSLog(#"This is an int: %d", anInt);
It's better to write the debug messages using debugger breakpoints instead of cluttering your code with NSLog messages. Breakpoints will also save you from having to remove all those log messages when you ship your app.
To do this, set a breakpoint in Xcode, double-click on it, and click the Add Action button in the pop-up window. Select "Log Message" and type your message. Check the "Automatically continue after evaluating" check box at the bottom to keep it from pausing execution on the breakpoint
I've tried creating a breakpoint within a class definition, stopping on the message sent to an object instance, hoping it would then jump to the class code and allow me to walk through line by line and see the values of the local variables.
However, I'm going to venture out and say "no, this should not be possible", as there could be multiple instances of the class in memory. If someone could give a better explanation, that would be grand.
(As a side note, my alternative is excessive NSLogging of the runtime data.)
Yes, it is possible! You can add a condition to a breakpoint:
http://d.pr/yZVB+
http://d.pr/pWOB+
The program will only pause at this breakpoint when the condition is satisfied. You could choose a condition such as self == _myGlobalInstanceOfInterest.
If you don't want to store the instance in a variable, you might, for example, start the breakpoint without a condition — and then when you figure out which instance you want as the program is running, use p myObject to get the address, and then just set the condition to use the that address (such as self == 0x8badf00d).
I take it you want to break upon a message being sent to a particular instance?
Read the Xcode documentation on breakpoints and watchpoints. Basically, you can set a condition on a breakpoint so that it will automatically continue if self isn't the instance you're interested in.
Assuming you're talking about something like this:
- (void)eatAPieceOfFruit: (NSFruit *)fruit {
NSString * fruitType = [fruit species];
BOOL hasSeeds = [fruit hasSeeds];
NSInteger deliciousnessRating = [self enjoymentOfFruitType: fruitType];
NSString * reactionToEating = [self phraseForFruitType: fruitType];
// Breakpoint set here
}
The debugger has access to and knows the name of any variable that's in scope -- any variable that you would be able to use in the actual code at the line where you broke, you can also get to via the debugger. So, at the debugger prompt, type:
po reactionToEating
(that's "po" for "print object"), or the name of any other local variable to see what it is. If you want to call a method on an object that's in scope you can do so:
print (int)[reactionToEating length]
po [reactionToEating capitalizedString]