#"%# in Objective C? - objective-c

I was following a tut and found a line of code like #"%# button pressed.". I'm pretty sure the relevant part is the %#, but is the first # an escape sequence or what?
Anyways, searching symbols doesn't go well in any search engine so I thought I'd ask. I think the %# is like {0} in C#?

%# is a format specifier. Functions such as NSLog and methods such as +stringWithFormat: will replace %# with the description of the provided Objective-C or Core Foundation object argument.
For example:
NSString *myName = #"dreamlax";
NSLog (#"My name is: %#", myName);
This will log the output "My name is: dreamlax". See here for more information format specifiers.
The initial # symbol at the beginning of the string tells the compiler to create a static instance of an NSString object. Without that initial # symbol, the compiler will create a simpler C-style string. Since C-style strings are not Objective-C objects you cannot add them to NSArray or NSDictionary objects, etc.

#"some string" means this is an NSString literal.
The string as show in #"CupOverflowException", is a constant
NSString object. The # sign is used
often in Objective-C to denote
extentions to the language. A C string
is just like C and C++, "String
constant", and is of type char *

I found this page which might help - http://www.yetanotherchris.me/home/2009/6/22/objective-c-by-example-for-a-c-developer.html
It seems that you are on the right track.

I'm still fairly new to the language, but it looks like the # specifies that the variable being passed/created is an NSObject, or a compiler directive.
As mentioned above, if you use it like this:
#"someText"
you're instantiating an NSString object, and setting the text of that object to someText. If you look at a good ol' C-style format specifier such as:
..."This is some text, and this is a float: %f", myFloat);
You're creating some text and telling the compiler to put the floating point string representation of myFloat into the string. %# is a format specifier, just like %f, %d, %c, %s and any other format specifier you're used to. However, if you use %# as follows:
... "This is some text, and this is an object:%#", myObject];
What you're doing is (I believe) telling the compiler that myObject is an object, and that you want it to include the output of the description method (ie. [myObject description]) in the string that you're creating.

Related

Objective-C equivalent of Swift "\(variable)"

The question title says it all, really. In swift you use "\()" for string interpolation of a variable. How does one do it with Objective-C?
There is no direct equivalent. The closest you will get is using a string format.
NSString *text = #"Tomiris";
NSString *someString = [NSString stringWithFormat:#"My name is %#", text];
Swift supports this as well:
let text = "Tomiris"
let someString = String(format: "My name is %#", text)
Of course when you use a format string like this (in either language), the biggest issue is that you need to use the correct format specifier for each type of variable. Use %# for object pointers. Use %d for integer types, etc. It's all documented.
#rmaddy's Answer is the gist of it. I just wanted to follow up on his comment that "It's all documented". Well, these symbols like %# and %d are called String Format Specifiers the documentation can be found at the following links.
Formatting String Objects
https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Strings/Articles/FormatStrings.html
String Format Specifiers
https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html#//apple_ref/doc/uid/TP40004265-SW1
Just telling us noobs "It's all documented" isn't very helpful because often (if you're like me) you googled to find this stackoverflow post at the top of the SEO. And taking the link in hopes of finding the original documentation!

Is the '#' that precedes NSStrings actually an overloaded operator?

When dealing with NSStrings we always need to include de # at the beginning of the string.
For example:
NSString *string = #"Hello, World!";
string is an object of the class NSString.
Just crossed my mind that # could be and overloaded operator that transforms the C string into an object of the class NSString.
Is it so? Or is it just a reverie of my noob mind?
# is the indicator to the compiler that you are declaring some kind of literal. NSString (#"") isn't the only one, NSDictionary (#{}), NSArray (#[]) and NSNumber (#1, #YES) also have defined literal definitions.
From here:
Using # should make it easier to bolt an Objective-C compiler on to an
existing C compiler. Because the # isn't valid in any context in C
except a string literal, the tokenizer (an early and simple step in
the compiler) could be modified to simply look for the # character
outside of a string constant (the tokenizer understands string
literals, so it is in a position to distinguish this). When # is
encountered the tokenizer would put the rest of the compiler in
"Objective-C mode." (The Objective-C parser would be responsible for
returning the compiler back to regular C mode when it detects the end
of the Objective-C code).
From the manual:
The NSString class provides an object wrapper for strings that has all
of the advantages you would expect, including built-in memory
management for storing arbitrary-length strings, support for Unicode,
printf-style formatting utilities, and more. Because such strings are
used commonly though, Objective-C provides a shorthand notation for
creating NSString objects from constant values. To use this shorthand,
all you have to do is precede a normal, double-quoted string with the
# symbol, as shown in the following examples:
NSString *myString = #"My String\n";
NSString *anotherString = [NSString stringWithFormat:#"%d %#", 1, #"String"];
// Create an Objective-C string from a C string
NSString *fromCString = [NSString stringWithCString:"A C string" encoding:NSASCIIStringEncoding];

How to do NSLog with variable

What should be the correct format of the below to print *newString ?
NSString *newString = #"Hello this is a string!";
NSLog(#newString);
NSLog works pretty much as a C printf, with the addition of the %# string format specifier, which is meant for objects. Being NSString an object, %# is the right format to use:
NSString *newString = #"Hello this is a string!";
NSLog(#"%#", newString);
For as tempting as it can look, NEVER do
NSLog(newString); //NONONONONO!
since it's a terrible practice that may lead to unexpected crashes (not to mention security issues).
More info on the subject: Warning: "format not a string literal and no format arguments"
The # symbol is just a shorthand for specifying some common Objective-C objects. #"..." represents a string (NSString to be specific, which is different from regular C strings), #[...] represents an array (NSArray), #{...} represents a dictionary (NSDictionary).
On the first line, you've already specified a NSString object using the # sign. newString is now an NSString instance. On the second line, you can just give it's variable name:
NSLog(newString);
You could theoretically just give the variable name, but it is a dangerous approach. If newString has any format specifiers, your app may crash/mess up (or access something that it shouldn't be accesing) because NSLog would try to read the arguments corresponding to the format specifiers, but the arguments don't exist. The safe solution would be NSLog(#"%#", newString);. The first argument to NSLog is now hard-coded and can't be changed. We now know that it will expect a single argument, that we are providing that argument, newString, so we are safe.
Because you've already specified a string and just passing that instance to NSLog, you don't need the # sign again.

Objective-C - NSLog - "%#" Referencing Character

I'm working through a BNR iOS Programming text and I came across this piece of code:
NSLog(#"%#", [items objectAtIndex:i]);
I am unsure of what "%#" is used for. I've seen other formats for referencing integers or characters, but I've never seen this.
I even checked this reference here and it had nothing.
Thanks!
%# is for printing objective-c objects.
To be a bit more precise. Every object is able to override
-(NSString *)description
This method is called when you use %#. It depends on the object what info of the object it will return in the NSString.
According to Apple:
Objective-C object, printed as the string returned by descriptionWithLocale: if available, or description otherwise. Also works with CFTypeRef objects, returning the result of the CFCopyDescription function.
Reference:
String Format Specifiers
I am working through the same text - and coming from a Java background, the "%#" formatter seems equivalent to the "toString" method that Java would have.
It is used to display custom information about an object.
There is a good example in the response to this StackOverflow question about the "toString()" equivalent.

Unfamiliar C syntax in Objective-C context

I am coming to Objective-C from C# without any intermediate knowledge of C. (Yes, yes, I will need to learn C at some point and I fully intend to.) In Apple's Certificate, Key, and Trust Services Programming Guide, there is the following code:
static const UInt8 publicKeyIdentifier[] = "com.apple.sample.publickey\0";
static const UInt8 privateKeyIdentifier[] = "com.apple.sample.privatekey\0";
I have an NSString that I would like to use as an identifier here and for the life of me I can't figure out how to get that into this data structure. Searching through Google has been fruitless also. I looked at the NSString Class Reference and looked at the UTF8String and getCharacters methods but I couldn't get the product into the structure.
What's the simple, easy trick I'm missing?
Those are C strings: Arrays (not NSArrays, but C arrays) of characters. The last character is a NUL, with the numeric value 0.
“UInt8” is the CoreServices name for an unsigned octet, which (on Mac OS X) is the same as an unsigned char.
static means that the array is specific to this file (if it's in file scope) or persists across function calls (if it's inside a method or function body).
const means just what you'd guess: You cannot change the characters in these arrays.
\0 is a NUL, but including it explicitly in a "" literal as shown in those examples is redundant. A "" literal (without the #) is NUL-terminated anyway.
C doesn't specify an encoding. On Mac OS X, it's generally something ASCII-compatible, usually UTF-8.
To convert an NSString to a C-string, use UTF8String or cStringUsingEncoding:. To have the NSString extract the C string into a buffer, use getCString:maxLength:encoding:.
I think some people are missing the point here. Everyone has explained the two constant arrays that are being set up for the tags, but if you want to use an NSString, you can simply add it to the attribute dictionary as-is. You don't have to convert it to anything. For example:
NSString *publicTag = #"com.apple.sample.publickey";
NSString *privateTag = #"com.apple.sample.privatekey";
The rest of the example stays exactly the same. In this case, there is no need for the C string literals at all.
Obtaining a char* (C string) from an NSString isn't the tricky part. (BTW, I'd also suggest UTF8String, it's much simpler.) The Apple-supplied code works because it's assigning a C string literal to the static const array variables. Assigning the result of a function or method call to a const will probably not work.
I recently answered an SO question about defining a constant in Objective-C, which should help your situation. You may have to compromise by getting rid of the const modifier. If it's declared static, you at least know that nobody outside the compilation unit where it's declared can reference it, so just make sure you don't let a reference to it "escape" such that other code could modify it via a pointer, etc.
However, as #Jason points out, you may not even need to convert it to a char* at all. The sample code creates an NSData object for each of these strings. You could just do something like this within the code (replacing steps 1 and 3):
NSData* publicTag = [#"com.apple.sample.publickey" dataUsingEncoding:NSUnicodeStringEncoding];
NSData* privateTag = [#"com.apple.sample.privatekey" dataUsingEncoding:NSUnicodeStringEncoding];
That sure seems easier to me than dealing with the C arrays if you already have an NSString.
try this
NSString *newString = #"This is a test string.";
char *theString;
theString = [newString cStringWithEncoding:[NSString defaultCStringEncoding]];