I finished writing a class' .h and .m files in objective c in XCode and want to see if all the class functions are implemented correctly. I have not set up anything in the storyboard file yet but would like to test and debug the code. I'm looking to simply declare an object of the class type and to run some of the functions on it similar to using the command line with Python.
If there's no way to simply debug code using command line commands, what would be the easiest way to set up the storyboard?
You can use the XCTest to test your classes.
You can find all the information you need in the Apple documentation is actually pretty easy to use.
https://developer.apple.com/Library/ios/documentation/DeveloperTools/Conceptual/testing_with_xcode/testing_2_testing_basics/testing_2_testing_basics.html#//apple_ref/doc/uid/TP40014132-CH3-SW1
If you want you can check this tutorial as well.
http://rshankar.com/test-driven-development-in-ios-beginners-tutorial-part-1/
If you want you can set break points as well and check that your code is executing properly. Sometimes when I just want to proof-test small classes I do it just setting a couple of break points instead of the XCTest classes but it all depends on your study case. If you have a decent amount of classes I would suggest to use XCTest to check that the classes are actually doing what is expected setting your assertions and the other conditions that XCTest offers as a framework.
Another way you can do your testing if applicable is using NSLog to print in console lines or values of interest at each stage of your code execution.
You mentioned the command line. If you set breakpoints you can use po objName to print the value or print varName to check values of objects and primitive variables correspondingly. po stands for print object and print well... There's different options if you feel comfortable using the console just set NSLogs at certain point of your code or set the break points and print the values using po or print commands in the console.
Here you can check the string format specifiers for NSLog which are the same ones used for NSString
https://developer.apple.com/library/ios/documentation/cocoa/conceptual/Strings/Articles/formatSpecifiers.html
Related
One feature I really appreciate in PyCharm is the evaluate expression window, where I can evaluate an expression and a block of code at breakpoint. I am wondering whether there is an equivalent / similar feature in Xcode for IOS development.
I have tried the following which does not give me what I need:
using "print" command in the debug console
using PO command to print object in debug console.
inserted "expression" in debug console.
Insert break point before and after the block of code which I want to evaluate
What I really need if possible is:
To be able to evaluate a block of code (after which, the value of the variables will be updated in the "variable watch window".
Change the expression / block of code to be evaluated at run time.
Once at break point, evaluate a block of code after the break point multiple times, without running the code before the break point again (this is the issue with inserting two breakpoints before and after the block of code, because I need to re-run the code before the first break point if I want to change my expression / block of code)
How can I automate setting a breakpoint on all methods in an Objective C class using lldb?
This is useful for learning the behavior of a complicated legacy class. I am using Xcode (includes lldb) for iOS development, and it is cumbersome to manually go through the (large) file in Xcode and click the gutter next to each method to set breakpoints.
One option is to use regex breakpoints.
breakpoint set -r '\[ClassName .*\]$'
You can play around with the regexp to suit your needs.
The command will create a breakpoint that stops on all methods implemented by that class. However, there will be no breakpoints on methods inherited from superclasses.
To get methods on the superclass, you'll have to use a conditional breakpoint. For example, if the superclass is UIViewController, you could do something like:
br s -r '\[UIViewController .*\]$' -c '(BOOL)[(id)$arg1 isKindOfClass:[CustomVC class]]'
For x86 change (id)$arg1 to *(id*)($ebp+8).
Finally, if you really want to learn about the control flow through various classes, check out dtrace. It's probably more suited to this than a debugger.
br se -f FooViewController.m -p '^#property|^ *- *\('
"br se" is short for "breakpoint set", pass your own filename to the -f argument, and the -p argument is a crude regex for properties and methods in Objective C.
Caveats: This doesn't seem to work for .h files, so if you have properties declared in the header that you want to watch then you may need to set watchpoints on their backing instance variables.
This is the best solution I have found so far, please post alternative solutions if you think they will be helpful.
I am running into a bizarre situation where a unit test's execution is behaving differently than the normal execution of a piece of code.
In particular, I am using a library called JSONModel, and when I am attempting to deserialize an object from a JSON string, one line in particular is causing problems when I step through the executing test case:
if ( [[property.type class] isSubclassOfClass:[JSONModel class]] ) ...
If I put a breakpoint before (or after) this line and execute:
expr [[property.type class] isSubclassOfClass:[JSONModel class]]
...in the debugger, it prints \x01 as the value (i.e. true), however when I actually step the instruction pointer, it behaves as though it is false, going instead into the else block. Again, typing the expression into the debugger again shows it as true even still.
I'm curious if anyone has seen similar behavior before and has any suggestions as to what could possibly be going wrong. I'm quite certain I'm not including different definitions for anything, unless Xcode has different internal cocoa class implementations for testing.
Update: Here's some even weirder evidence: I've added some NSLog statements to get an idea for how the execution is seeing things. If I log property.type.superclass I get JSONModel back (as expected); however if I log property.type.superclass == [JSONModel class] I get false!
To me this is indicating that the JSONModel the unit test execution is seeing is somehow a different JSONModel class that I'm seeing at runtime (and what it should be seeing). However, how that is happening I can't figure out.
Could this be caused by a forward class declaration or something like that?
Well I seem to have discovered a "solution" by experimentation. It turns out if I replace [JSONModel class] with NSClassFromString(#"JSONModel") it works swimmingly!
Now why this is I cannot say, and will give the answer to whoever can explain it!
I had the exact same problem, here's what was happening.
As expected with this kind of behaviour, it was an issue with the class being duplicated. As with you, [instance class] and NSClassFromString would return different values. However, the class were identical in all points : same ivar, same methods (checked with the obj runtime). No warning was displayed at compile, link and/or runtime
In my case, the tests were about a static library used in my main application (Bar.app).
Basically, I had 3 targets:
libFoo
libFooTests
Bar.app
The tests were performing on the device, and not on simulator. As such, they needed to be logic tests, and not unit tests, and had to be loaded into an application. The bundle loader was my main app, Bar.app.
Only additional linker flag was -ObjC
Now, Bar.app was linking libFoo.
It turns out, libFooTests was also linking libFoo.
When injecting libFooTests in the test host (Bar.app), symbols were duplicated, but no warning were presented to me. This is how this particular class got duplicated.
Simply removing libFoo from the list of libraries to link against in libFooTests did the trick.
What do I need to do to have variables display their values in XCode?
I don't have it in Auto pane, and it also does not show when I hover over it. Why is that?
I can go Add Expression and sometimes it will display it correctly, and I can also do NSLog and log it, but this seems really ridiculous in the year of 2013.
I am using XCode 4.6. Am I doing something wrong, or this basic functionality just does not exist?
You can use the local variables section in the content pane to view variable values while debugging:
You can use shift + command + Y to toggle the above pane.
For more information regarding debugging in xCode, check out the following link.
In the console use the command 'po' (stands for print object)
e.g. po [self myVariable]
This will give you more information than this semi-useless variable tree in the content pane.
hints:
1) Make sure your build configuration is set to Debug, or you can't debug local variables.
2) Sometimes you need to debug structs and primitives, in this case use 'p' instead of 'po'
3) you can use dot notation (po self.myVariable), but for some data types this doesn't seem to work. I believe it depends on your xcode version
As the title said, I want to debug some Core Data bugs. Instead of using NSLog everywhere in the code, is it possible to watch a entity's attributes in XCode 4's watch window? Like the "quick watch" tool in Entity Framework 4.0 of .NET.
Any value that has a named variable assigned to it can be viewed in the debugger. In Xcode 4 it appears in the debugger's left column. If you select the variable, you can use the contextual menu option "Print to console" to have a detailed description printed to the debugger console. This is useful when examining managed objects as they often contain more info than the list of variables can cleanly display.
(See- Xcode 4 Transition Guide:Control Program Execution in the Debug Area and Source Editor, Figure 5-9
In addition, you can issue any of the standard gdb commands from the command line in the debugger console. The most useful of the these commands is po which stands for print object. Say you have an object myObject that has a property aProperty. You could examine it directly by using:
po [myObject valueForKey:#"aProperty"]
If you create NSManagedObject subclasses, you also have the option of overriding the description method which allows you to produce custom descriptions of the object which will show up in print to console and the po command.