Is NSLog meant as a general purpose write? - objective-c

In objective-c when I create a new project I get this in the main:
NSLog(#"Hello, World!");
I cannot find any other easy writing methods in the Foundation library.
Is NSLog the printf of objective-c? is it recommended to use it in production for printing on screen (of command line tools)?
If not, how can I print to screen using the Foundation library?
Edit:
It looks like NSLog also adds timestamp and things, I thought thats only the Xcode console.
How can I print objective c objects using a format like NSLog without timestamps?

Objective C is a superset of C, so you can still use your printf, scanf, etc. NSLog prints timestamp and some process information, and shows up in the system Console. NSLog also knows how to print Obj-C objects (use the %# format specifier).

If you like, you can do what I usually do: define my own printing function that works just as well, minus the timestamp:
void IFPrint (NSString *format, ...) {
if (!format) return;
va_list arguments;
va_start(arguments, format);
fputs([[[[NSString alloc] initWithFormat:format arguments:arguments] autorelease] UTF8String], stdout); // Omit autorelease call if using ARC.
va_end(arguments);
}
The way this works is that it uses NSString's text parsing (exactly how you use %# to print objects via NSLog), and prints it out very simply to the screen. It's faster than NSLog, and doesn't go through the system log service.

You can use printf. NSLog is convenient if you are printing NSStrings and other Objective-C objects.

NSLog is intended for writing debug trace to the console. Objective-c is not really geared towards developing a console based application, so if that was what you were intending, I would either look at the underlying C libraries and use printf and scanf, or a framework like this:
Objective-C Command Line Framework
In terms of how you can print out the object's description without the NSLog's timestamp information, I would use printf to print the output of [[myObject description] UTF8String], as I presume that's what NSLog uses when you print out the object using the %# format specifier.

Related

How to print something to the console in Xcode?

How do you print something to the console of Xcode, and is it possible to view the Xcode console from the app itself?
Thanks!
How to print:
NSLog(#"Something To Print");
Or
NSString * someString = #"Something To Print";
NSLog(#"%#", someString);
For other types of variables, use:
NSLog(#"%#", someObject);
NSLog(#"%i", someInt);
NSLog(#"%f", someFloat);
/// etc...
Can you show it in phone?
Not by default, but you could set up a display to show you.
Update for Swift
print("Print this string")
print("Print this \(variable)")
print("Print this ", variable)
print(variable)
#Logan has put this perfectly. Potentially something worth pointing out also is that you can use
printf(whatever you want to print);
For example if you were printing a string:
printf("hello");
3 ways to do this:
In C Language (Command Line Tool) Works with Objective C, too:
printf("Hello World");
In Objective C:
NSLog(#"Hello, World!");
In Objective C with variables:
NSString * myString = #"Hello World";
NSLog(#"%#", myString);
In the code with variables, the variable created with class, NSString was outputted be NSLog. The %# represents text as a variable.
#Logan said it perfectly. but i would like to add an alternative here,
if you want to view logs from just your application then you can make
a custom method that keeps saving the log to a file in documents
directory & then you can view that log file from your application.
There is one good advantage for developers of the app after the app has been released & users are downloading it. Because your app will be able to send logs & crash reports to the developers (of course with the permissions of the device user !!!) & it'll be the way to improve your application.
Let me know (To other SO users), if there is another way of doing the same thing. (Like default Apple feature or something)
Let me know if it helps or you want some more idea.
You can also use breakpoints. Assuming the value you want is defined within the scope of your breakpoint you have 3 options:
print it in console doing:
po some_paramter
Bare in mind in objective-c for properties you can't use self.
po _someProperty
po self.someProperty // would not work
po stands for print object.
Or can just use Xcode 'Variable Views' . See the image
I highly recommend seeing Debugging with Xcode from Apple
Or just hover over within your code. Like the image below.
In some environments, NSLog() will be unresponsive. But there are other ways to get output...
NSString* url = #"someurlstring";
printf("%s", [url UTF8String]);
By using printf with the appropriate parameters, we can display things this way. This is the only way I have found to work on online Objective-C sandbox environments.
In Swift with Xcode you can use either print() or NSLog().
print() just outputs your text. Nothing more.
NSLog() additionally to your text outputs time and other useful info to debug console.

Why can't LLDB evaluate this expression?

Neither one of these statements can be processed by LLDB... why is it unable to come up with the NSString result and print it out
expr -o -- [NSString stringWithFormat:#"%#", #"Wow this doesnt work??"]
po [NSString stringWithFormat:#"%#", #"Wow this doesnt work??"]
It seems that the expression command in lldb can generally not evaluate functions with
variable argument lists. It fails even with a simple C function:
int foo(char *msg, ...)
{
return 17;
}
(lldb) expr foo("bar")
(int) $2 = 17
(lldb) expr foo("bar", 2)
error: no matching function for call to 'foo'
note: candidate function not viable: requires 1 argument, but 2 were provided
error: 1 errors parsing expression
So this looks like a bug (or non-feature) in lldb.
This is more of academic than practical interest, but the original question and Martin's answer actually have different causes. In both cases, lldb is actually correctly refusing to call a function with more arguments than it is declared to have, but getting the actual definition wrong for different reasons.
In the first case, lldb doesn't actually have debug information for the method call [NSString stringWithFormat:format, ...]. It turns out the compiler does not emit debug information for every function your program USES, only the ones it defines. This restriction is mostly to keep the size of the debug information manageable.
So the debugger has to consult the ObjC runtime for extra type information for these kit functions. But the runtime type information doesn't encode the variable argument-ness of variable argument functions.
In the second case, what you are seeing is actually a bug in clang's debug output. It fails to emit the bit of information that tells the debugger that the function is a variable argument function.
In any case, in lldb you can work around this sort of issue by introducing declarations of commonly used functions to lldb's expression parser using the "expr-prefix" file. For instance, in Martin's case, I make a file "/tmp/expr-prefix.lldb" containing the line:
extern "C" int foo (char *msg, ...);
Then in lldb, I do:
(lldb) settings set target.expr-prefix /tmp/expr-prefix.lldb
And then you can call the function in the expression parser. A couple of caveats with this feature. This "expression prefix" file gets included in all the expression you run with the "print" command, so don't put too much stuff in there or it will slow down general expression parsing. Don't try to do things like:
#import <Cocoa/Cocoa.h>
that will be very slow and probably won't work anyway - since this depends on a whole set of #defines that the debugger doesn't know about.
But it can be very helpful if you have a few functions like this that you really need to call, but can't because we either don't know the signature or are somehow getting it wrong.
The extern "C" is required because lldb parses expressions as ObjC++.
If you want to prototype an ObjC method, you need to do it on an extension of the class you are prototyping the method for; we often have a rudimentary class def'n and the compiler doesn't like to add methods to a known class, only extensions.
I found a workaround in this article:
http://www.cimgf.com/2012/12/13/xcode-lldb-tutorial/
For example when I try to use this syntax to call method:
po [NSString stringWithFormat:#"%#", #"MyName"];
Debugger error is:
error: too many arguments to method call, expected 1, have 2
error: 1 errors parsing expression
But you can try this one:
po [[NSString alloc] initWithFormat:#"%#", #"MyName"];
Debugger message is:
$4 = 0x0a6737f0 MyName
import UIKit in debugger this worked for me
expr #import UIKit

Viewing NSData contents in Xcode

I am running Xcode and I would like to dump out a NSData*. The variable in question is buffer. Is there a way to do this through the UI or the GDB debugger?
Edit
I've moved my notes into an answer.
No one has ever correctly answered the question. After 2 years I think it's time for one :)
Assuming you have in your code
NSData* myData;
Then in lldb you type
me read `[myData bytes]` -c`[myData length]`
If the format of the dump is not to your liking you can add '-t ' for example
me read `[myData bytes]` -c`[myData length]` -t int
For more help type
help me read
in lldb
From Xcode 5 (lldb), you can use the following:
po (NSString *)[[NSString alloc] initWithData:buffer encoding:4]
Note that this assumes your NSData instance is encoded with NSUTF8StringEncoding, but you can look up the other values in the headers or the documentation.
So if you're debugging something like a JSON request that's wrapped up in an NSURLSessionDataTask, the request data is in task.originalRequest.httpBody, and you can view that in the debugger with
po (NSString *)[[NSString alloc] initWithData:task.originalRequest.HTTPBody encoding:4]
In lldb, the following works to let you examine the contents of NSData objects:
You can get the address of the bytes for use with various debugger commands like this:
p (void *)[buffer bytes]
You see something like this:
(void *) $32 = 0x0b5e11f0
If you know the underlying data is a string, you can do this:
p (char *)[buffer bytes]
and the debugger will output:
(char *) $33 = 0x0b5e11f0 "This is the string in your NSData, for example."
In Swift this should do the trick:
po String(data:buffer!, encoding: NSUTF8StringEncoding)
Right click buffer and click on Print description of "buffer".
The console should say
Printing description of buffer:
<your data here ...>
Unfortunately, none of the suggestions so far solved the problem of actually being able to quickly display the data inside NSData.
I wrote a simple method that works the way I need it to. From the GDB window, I can type in print [Util dumpData:theData] and I will get nice, formatted output.
+(void) dumpData:(NSData *)data
{
unsigned char* bytes = (unsigned char*) [data bytes];
for(int i=0;i< [data length];i++)
{
NSString* op = [NSString stringWithFormat:#"%d:%X",i,bytes[i],nil];
NSLog(#"%#", op);
}
}
NsLog Output
0:24
1:0
2:4
3:0
4:0
5:0
Your data instance is empty.
It wouldn't only display the address otherwise. -[NSData description] includes a printout of the contents of the data. The bytes are grouped in fours and printed in hex with a leading 0 placeholder:
char arr[] = {0x1, 0x2, 0xA, 0x4, 0xF};
NSData * dat = [NSData dataWithBytes:arr length:5];
NSLog(#"%#", dat);
2012-07-17 22:24:48.973 PrintDat[61264:403] <01020a04 0f>
Using po dat at the debugger's command line will give you the same results, including the address:
(NSData *) $1 = 0x00007f98da500180 <01020a04 0f>
The contextual menu route that Anshu suggested also uses the description method.
I think I have it now.
Right click on NSData in the list displayed there, and click 'Show Memory Of "x"'.
I posted this as an answer to this relevant question:
Once you place a breakpoint, run, and the program stops at the breakpoint, hover your cursor over the variable/value you want to see like this:
You could also place an NSLog(#"%#", yourLabel.text); to view the contents of that label/other object type.
One other option is to run GDB in the console like this:
gdb
attach <your process name>
And then use the po (print-object) command to view the value of a variable like this:
po variableName
To view the value of primitive types (int, float, long, double, char, etc.), you can just use the print command while running GDB in the console like this:
print yourPrimitiveVariable
Hope this helps!
EDIT:
With the po command, you can print out the value of an object using both the property name (self.myProperty) or the ivar name (possibly _myProperty). I demonstrate this here:
Xcode 11.4 (and probably earlier) supports examining the raw bytes of (NS)Data in the visual debugger. Set a breakpoint after the Data has been assigned, hover over the symbol until the popup appears, and click on the eye or info icon. Roll for dexterity to prevent the popup from closing on you by moving outside of the tiny target.
Tested with Swift but presumably works with C family languages, too.
(Note: the eye icon produces the output below which is nicely formatted but, uh... seems to be missing the final column of bytes?)
The easiest way for me (during local development only!) is to convert to unused NSString instances. Then the values show right up in the debugger. Once I'm finished, I nuke those lines of code.
From this old thread
NSString* newStr = [[NSString alloc] initWithData:theData encoding:NSUTF8StringEncoding];
For Swift code I'm doing the following:
When my program is stopped in a breakpoint I use the "Add expression" option and enter [UInt8](data) where data is my Data instance:
After that I can see the data contents:

UIImage imageNamed size

New to Objective-C, Cocoa, and compiled languages in general so forgive my ignorance:
UIImage *myImage = [UIImage imageNamed:#"1-filter.jpg"];
NSLog(#"myImage.size=%#", myImage.size);
Results in
Thread 1: Porgram received signal: "EXC_BAD_ACCESS".
Why? How do I get the size of a UIImage?
The size is a structure.
Use either size.width, size.height or NSStringFromCGSize(myImage.size) for NSLog output.
This is a subtle, annoying-for-beginners error. (I actually just ran into this last week.)
When you use the format string %# in an NSLog, the argument must be some kind of Objective-C object. (Behind the scenes, when you do NSLog(#"%#", foo), the system calls [foo description] to figure out what string to output. If the variable you pass to NSLog is not an Objective-C object, the system will try to send a message to something that isn’t an object and then throw this error.)
In this particular case, you’re going to be getting an integer, so replace %# with %d in your format string to make everything work okay.
Additionally, as Eugene mentioned, you want to be accessing a part of the size object. So try
NSLog(#"size.height=%d", myImage.size.height);
Edit: this should actually be %f instead of %d, and please read the comments on this answer.

How to NSLog calling function

Not the function calling the NSLog or Dlog but function that call that function.
I created a class
+(void) computeTime:(void (^)())block
{
NSDate * currentTime = [NSDate date];
block();
DLog ("Time Running is: %f", [[NSDate date] timeIntervalSinceDate:currentTime);
}
So everytime there is an operation whose time I want to measure I will put that in a block instead.
and do [Tools computeTime:^{//operation}];
However, I want to know the function that call that computeTime. How do I do so?
Two options:
The first is to abuse +[NSThread callStackSymbols] to get an array of all the symbols in the call stack and pull out the one you want. I suspect this is going to be relatively slow.
The second is to use a macro. The C preprocessor provides a nice macro called __PRETTY_FUNCTION__ which contains the name of the function all nicely formatted, and it works well for Obj-C methods as well. Instead of [Tools computeTime:^{/*operation*/}] you can either use something like [Tools computeTimeWithName:__PRETTY_FUNCTION__ block:^{/*operation*/}] or you could wrap it all up in your own macro so you can say TOOLS_COMPUTE_TIME(^{/*operation*/}):
#define TOOLS_COMPUTE_TIME(...) [Tools computeTimeWithName:__PRETTY_FUNCTION__ block:(__VA_ARGS__)]
Note, I've used a varargs-style macro because the C Preprocessor doesn't understand obj-c syntax very well, so any commas inside your block will be interpreted as separate arguments to the macro. If I defined it using TOOLS_COMPUTE_TIME(op) then the compiler would complain that the macro only takes 1 argument but it was given multiple. By using varargs the compiler doesn't care how many arguments you give it, and it will pass them all on to the __VA_ARGS__ token.
Another possible answer for someone searching for the OP's original question and adding to Kevin's first suggestion to use the call stack.
If you're looking for what called a function (method), consider the following:
NSArray *callStack = [NSThread callStackSymbols];
// Top of the stack. Current method
NSLog(#"Current method: %#", [callStack objectAtIndex:0]);
// Called by
NSLog(#"called by: %#", [callStack objectAtIndex:1]);
It is possible that the stack item looked for is further into stackArray.
Hope this helps find a bug quicker.