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

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.

Related

Line of code from Swift to Objective-C

I'm quite blank when it comes to swift, I've been developing using Obj-c. But a tutorial that I've been following uses Swift. Can anyone help me convert the following line of Swift into Objective-C. It's basically to load a String onto an Array.
self.iDArray.append(objectIDs[i].valueForKey("objectId") as! String)
self.iDArray.append(objectIDs[i].valueForKey("objectId") as! String)
Should be
[self.iDArray append: [objectIDs[1].valueForKey: #"objectID"]]
However, the Swift code is force-casting [objectIDs[1].valueForKey: #"objectID"] to type String (A Swift string).
That suggests to me that self.iDArray may be a Swift array. Swift arrays normally contain only a single type. You create an array of String objects, or an array of Dictionary objects. You can also create an array of AnyObject.
NSArray is an array of id type.
I'm not 100% positive how to force-cast to String type in Objective-C. maybe:
[self.iDArray append: (String) [objectIDs[1] valueForKey: #"objectID"]]
On the surface, objectIDs[x] appears to be a dictionary, and the compiler will give you a break on types if you dereference it that way. So naive to parse, a usable syntax would be:
[self.iDArray append:objectIDs[1][#"objectId"]];
But that's incorrect semantically for parse, since the implication is that the objectIDs array is implied to contain parse objects (named confusingly with the "IDs" suffix). If it's really parse objects, then the collection style reference for objectId won't work, and should be instead
[self.iDArray append:((PFObject *)objectIDs[1]).objectId];
Or more readably:
PFObject *object = objectIDs[1];
NSString *objectId = object.objectId;
[self.iDArray append:objectId];
But, along the same lines semantically, the implication of the code is that it's adding to an NSMutable array, so it probably should be -- for any of the above suggestions:
[self.iDArray addObject: .....
Stop reading here if you care only about compiling and executing without a crash.
But, even if all that's right, which I think can be inferred from the code, it's indicative of bad design in my opinion. Swift developers in particular seem to have a penchant for saving off objectIDs and passing them around as proxies for object, and in so doing, loosing all of the other valuable stuff in the PFObject.
My practice is, wherever possible, just keep and pass the whole PFObject. You can always ask it for its objectId, later. More strongly, my rule of thumb when reading code is: show me parse.com code that refers much to objectIds -- except for things like equality tests -- and I'll show you a design error.

Does Objective-C have a method (or C function) returning object's format specifier for a given object?

I want to write my own method to make inspection of variables easier than I have it with NSLog - I want it to be a wrapper around the NSLog, so I need to somehow recognize a proper format specifier for any object passed to my method.
It would be nice to have a method like format_specifier_for that could do the following:
format_specifier_for(1) => %d
format_specifier_for(#1) => %#
and so on...
UPDATE:
Besides the accepted answer (it does answer the original question) there are two possible approaches to the problem:
From #Guillaume's answer: use LOG_EXPR method from http://vgable.com/blog/2010/08/19/the-most-useful-objective-c-code-ive-ever-written/.
Use overloadable attribute when defining methods as described here: How to check if a variable is an object?
I think the ideal solution could borrow from both of these options.
No, there cannot be such a function since you can always use several (in theory every one) format specifiers for the same data type. For example you can use %# to print the value of a NSString or %p to get the address in memory.
Look at that: The Most Useful Objective-C Code I've Ever Written. The author uses the C typeof operator and the Objective-C #encode directive to do something like you want...

NSMutableDictionary setObjetct forKey id NSString

Frankly, it is rather a detail question.
Apples documentation of NSMutableDictionary https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSMutableDictionary_Class/Reference/Reference.html states:
setObject:forKey:
Adds a given key-value pair to the dictionary.
- (void)setObject:(id)anObject forKey:(id)aKey
According to that the parameter forKey accepts any object. However, when I try to pass an NSNumber Incompatible pointer types sending 'NSNumber *' to parameter of type 'NSString *'
Aparently some NSString only is accepted as key.
For the time beeing I will convert my number to a string. In the end it is just a key. But does anybody know who is right? The documentation or the compiler?
You shouldn't get that warning when using setObject:forKey:. However, you will get that warning when using the similarly-named setValue:forKey:. The latter, while it appears similar in name, is part of the key-value coding system and thus only accepts an NSString as the key.
Here's a sample program to demonstrate the difference.
Apple's documentation is right, maybe you were confusing the method setObject forKey with the setValue forKey as #mipadi said.
this works fine:
[someMutableDictionary setObject:#"a string" forKey:[NSNumber numberWithInt:1]];
what does your code look like?

XCode - Printing Live Values of objects

Hi I am debugging and need to be able to check what the values of my properties within my objects are. They are strings... but I dont see the actual string itself.
I just get this here:
some advice would be nice...
thanks
Add below method to TrackVO class
- (NSString *)description{
return #"put together your instance property values and send out";
}
Note:
You are overriding the method that is inherited from NSObject.
%# and xCode-variable-view will implicitly call this description method.
The debugger sometimes messes up the contents of variables. Try logging your strings.
NSLog(#"String value: %#", myString);

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