Difference between NSString and # along with a string in objective c [duplicate] - objective-c

I've been using Objective-C for a while now, but have never really understood what the purpose of the # symbol before all strings is. For instance, why do you have to declare a string like this:
NSString *string = #"This is a string";
and not like this:
NSString *anotherString = "This is another string";
as you do in Java or so many other programming languages. Is there a good reason?

It denotes a NSString (rather than a standard C string)
an NSString is an Object that stores a unicode string and provides a bunch of method to assist with manipulating.
a C string is just a \0 terminated bunch of characters (bytes).
EDIT: and the good reason is that Objective-C builds on top of C, the C language constructs need to be still available. #"" is an objective-c only extension.

Related

How to convert c++ std::u32string to NSString?

I am developing a bridge between C++ and swift. And I need to convert C++ std::u32string to NSString. Here the code I tried:
u32string str = U"some string";
NSLog(#"%#", [[NSString alloc] initWithBytes:str.data() length:str.size() * sizeof(char32_t) encoding:NSUTF32StringEncoding]);
However initWithBytes returns nil.
Don't ask me why, but it seems to work if:
I insert a byte order mark (BOM) at the start of the string:u32string str = U"\uFEFFsome string";
or I use NSUTF32LittleEndianStringEncoding instead of NSUTF32StringEncoding.
Inserting byte order marks all over the place isn't terribly practical, so I guess you need to define your own constant which evaluates to either the little or big endian versions of the encoding constant depending on the platform being compiled.
This appears to be a quirk in Foundation, nothing specific to Objective-C++ or your use of std::u32string.

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];

objective-c strings: why don't you need a setter/getter?

I'm just beginning, and I'm a little hung up on this. I may have a fundamental misunderstanding with which you can kindly help me out.
Why is it that you can assign a string value to an NSString* (and, I'm sure, many other object types) directly? E.g.,
NSString* s = #"Hello, world!";
whereas the following code, I believe, would assign to s2 s1's pointer value (and therefore only incidentally provide s2 with a string value)?
NSString* s1 = #"Hello, world!";
NSString* s2 = s1;
For many objects, don't you have to indicate a property, a.k.a. instance variable, to which you want to assign a value (i.e., use a setter method)? Shouldn't the object itself accept assignments only of pointer values? Or do classes such as NSString automatically reinterpret code such as the first example above to assign the indicated string to an implied instance variable using an implied setter?
Why is it that you can assign a string value to an NSString* (and, I'm
sure, many other object types) directly?
Though it may look like it, you are not assigning the value of the string 'directly' to the instance variable. You are actually assigning the address of the string value to your instance variable. Now, the real question is what is going on behind the scenes when you have an expression of the type:
NSString * str = #"Hello World";
This expression represents the creation of a string literal. In C (and Objective-C which is a strict superset of C), string literals get special handling. Specifically, the following happens:
When your code is compiled the string "Hello World" will be created in the data section of
the program.
When the program is executing, an instance variable 'str' will be allocated on the heap.
The 'str' instance variable will be pointed at the static memory location where the actual string "Hello World" is stored.
The main difference between your first and second examples is that in the second example the memory for the string variable is dynamically allocated on the heap, at runtime. Note that in both cases the variable 'str' is just a pointer allocated dynamically.
More or less the latter. String literals like #"Hello World!" are treated as a special case in Objective-C: strings declared with that syntax are statically allocated, instantiated and cached at compile time to improve performance. From the programmer's perspective, it's no different from calling [NSString stringWithString:#"Hello World!"] or a constructor that takes a C-string -- you should just think of it as syntactic sugar.
FWIW, Objective-C has recently begun extending the # prefix to allow declaring dictionary and array literals as well, e.g.: #{ #"key" : #"value" } or #[ obj1, obj2, obj3 ].
This is a function of the compiler and not a language construct. The compiler in this case recognizes a string literal and inserts some code to produce the intended result.
#"" is essentially shorthand for NSString's +stringWithUTF8String method.
take from here:
What does the # symbol represent in objective-c?
NSString *s1 = #"Hello, world!";
is essentially equivalent to
NSString *s1 = [NSString stringWithUTF8String:"Hello, world!"];
The former allocates a new NSString object statically (instead of on the heap at runtime, as the latter would do).
It's important to note that these are just pointers. When you do NSString *s2 = s1, both s1 and s2 refer to the same object.

#"%# in 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.

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]];