Difference between (25) and #(25) - objective-c

I have been brushing up on my objective-c and one of the exercises that I am working on deals with UIInterpolatingMotionEffect objects. 2 properties from that class are minimumRelativeValue and maximumRelativeValue. In the exercise they have them as the following:
motionEffect.minimumRelativeValue = #(-25);
motionEffect.maximumRelativeValue = #(25);
I know that in obj-c you use # for the following (from wikipedia):
Used to avoid taking english words and making them reserved (for example, you can't have a variable called float in C/Objective-C because this is a reserved word).
With that being said, what would be the difference between using #(-25) and (-25) in the above example?

25 is a number. #(25) is an NSNumber object with value 25. It is equal to
[NSNumber numberWithInt:25];
In some cases you have to wrap numbers with NSNumber. For example you can not add number to NSArray / NSMutableArray.
You may read more about Objective C literals here https://www.mikeash.com/pyblog/friday-qa-2012-06-22-objective-c-literals.html

(-25) is just -25 with brackets around. You can add backets to lots of numerical or logical expessions without (or sometimes with) changing its value.
The # is one of the object creation shortcuts in objective-c. In this case it is equivalent to #-25 (Frankly, I am not sure whether there needs to be the brackets here because of the minus) which is equivalent to [NSNumber numberWithInt:-25].
See more of them here: http://clang.llvm.org/docs/ObjectiveCLiterals.html

Related

Why do objective-c array parameters not use colon notation?

Im currently learning some objective-c from the big ranch guide book. My understanding is that methods with multiple parameters use colons to separate each parameter, but when reading about creating arrays, i found this snippet of code:
NSArray *dateList = [NSArray arrayWithObjects:now, tomorrow, yesterday, nil];
This has left me confused as i thought objective-c method parameters must each be preceded by a portion of the method name along with a colon. Can anybody explain this to me?
This is an exception to the rule; this is commonly called a variadic method. If you look at the definition in NSArray.h:
+ (instancetype)arrayWithObjects:(id)firstObj, ... NS_REQUIRES_NIL_TERMINATION;
you see that you can specify an arbitrary number of parameters, as long as the last one is nil (this is called the sentinel).
This saves the developers from creating a large number of different methods having roughly the same functionality, each of which accept a different number of parameters. They did so in NSObject, where you have
- (id)performSelector:(SEL)aSelector withObject:(id)object1;
- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;
(but no further methods).
The method only has one parameter, a variable parameter list.
Here is the Objective-C declaration from the Apple Developer website:
+ (instancetype nonnull)arrayWithObjects:(ObjectType nonnull)firstObj, ...;
There's no need for colon separation, because the object list is treated as one parameter, even thought it looks like many parameters!

Why are instances created using a 'literal syntax' known as 'literals'?

Something that is bothering me is why the term 'literal' is used to refer to instances of classes like NSString and NSArray. I had only seen the term used in reference to NSString and being naive I thought it had something to do with it 'literally' being a string, that is between quotation markers. Sorry if that sounds pathetic, but that was how I had been thinking about it.
Then today I learned that certain instances of NSArray can also be referred to as literal instances, i.e. an instance of the class created using a 'literal syntax'.
As #Linuxios notes, literal syntaxes are built into the language. They're broader than you think, though. A literal just means that an actual value is encoded in the source. So there are quite a few literal syntaxes in ObjC. For example:
1 - int
1.0 - double
1.0f - float
"a" - C-string
#"a" - NSString
#[] - NSArray
^{} - function
Yeah, blocks are just function literals. They are an anonymous value that is assignable to a symbol name (such as a variable or constant).
Generally speaking, literals can be stored in the text segment and be computed at compile time (rather than at run time). If I remember correctly, array literals are currently expanded into the equivalent code and evaluated at runtime, but #"..." string literals are encoded into the binary as static data (at least now they are; non-Apple versions of gcc used to encode an actual function call to construct static strings as I remember).
A literal syntax or a literal is just an object that was created using a dedicated syntax built into the language instead of using the normal syntax for object creation (whatever that is).
Here I create a literal array:
NSArray* a = #[#"Hello", #"World"];
Which is, for all intents and purposes equivalent to this:
NSArray* a = [NSArray arrayWithObjects:#"Hello", #"World", nil];
The first is called a literal because the #[] syntax is built into the language for creating arrays, in the same way that the #"..." syntax is built in for creating NSStrings.
the term 'literal' is used to refer to instances of classes
It's not referring to the instance really; after the object is created, the way it was created doesn't matter:
NSArray * thisWasCreatedWithALiteral = #[#1, #2];
NSArray * butWhoCares = thisWasCreatedWithALiteral;
The "literal" part is just the special syntax #[#1, #2], and
it ha[s] something to do with it 'literally' being a string, that is between quotation markers.
is exactly right: this is a written-out representation of the array, as opposed to one created with a constructor method like arrayWithObjects:

What does #() mean in Objective-C?

For example,
CABasicAnimation *rotate = [CABasicAnimation animationWithKeyPath:#"transform.rotation"];
[rotate setToValue:#(M_PI)];
[rotate setDuration:0.1f];
[[aView layer] addAnimation:rotate forKey:#"myRotationAnimation"];
where M_PI is defined as a macro in math.h,
#define M_PI 3.14159265358979323846264338327950288 /* pi */
It's a pointer to an NSNumber object. It's called a boxed literal, because the mental picture is of putting a primitive value of expression inside into a "box", that is, an object.
See official documentation if in doubt. Note that pointer can be to a "real" NSNumber object or it can (theoretically, don't know whether this will work in practice) be a tagged pointer (see, e.g., my question).
Note that you can also do things like #"string" and #5, which will create constants in compile time. But you need parentheses to use something which is not a literal, e.g. #(2 + 3). Parentheses form can be used for any expression, even those that compiler cannot compute at compile-time (although if it can, it will just put an expression result into code).
NeXT and Apple Obj-C runtimes have long included a short-form way to create new strings, using the literal syntax #"a new string". Using this format saves the programmer from having to use the longer initWithString or similar methods when doing certain operations.
When using Apple LLVM compiler 4.0 or later, arrays, dictionaries, and numbers (NSArray, NSDictionary, NSNumber classes) can also be created using literal syntax instead of methods. Literal syntax uses the # symbol combined with [], {}, (), to create the classes mentioned above, respectively.
So, basically it's not only for id or NSNumber object!
thanks to wiki.
It's Shorthand writing
In Objective-C, any character, numeric or boolean literal prefixed with the '#' character will evaluate to a pointer to an NSNumber object (In this case), initialized with that value. C’s type suffixes may be used to control the size of numeric literals.
'#' is used a lot in the objective-C world. It is mostly used to avoid taking english words and making them reserved (for example, you can't have a variable called float in C/Objective-C because this is a reserved word).
Use this link To have detailed knowledge of '#' symbol.
In Modern Objective C, '#' symbol is used extensively.
What You can do with it:
calculate an expression: #(<Expression>)
wrap any value like int,bool,float,char in same way
Reasons to use:
Easy to write, Less code required
Less chances of mistakes. Compare [NSNumber numberWithInt:3] with #3.
Get rid of typecasting issues in simple cases.
It represent id Object
that you can use any expression in it or return any object.
Syntax : #(<#expression#>) it will return id object.
So in your case it will returning NSNumber object to setToValue method.

Is there a modern Obj-C short notation like #[array] or #{#"dict":dict} for CGPoint or NSPoint?

This is great:
NSArray *myArray = #[0, M_PI];
NSDictionary *myDict = #{#"item":anItem, #"another":somethingElse};
//etc.
But this is tedious:
[baseline moveToPoint:NSPointFromCGPoint(CGPointMake(0, baselinePosition))];
[baseline lineToPoint:NSPointFromCGPoint(CGPointMake(self.bounds.size.width, baselinePosition))];
Is there anything like #(0, 0) to simplify writing a point literal in code?
C99 compound literals to the rescue:
(CGPoint){ 0, 0 }
or
(NSPoint){ 0, 0 }
As H2CO3 points out, you can just cast a literal - this is plain old C, and NSPoints and CGPoints are just C structs. nothing fancy here.
As a consequence, there is no Objective-C shortcut, modern or otherwise, but there is an old macro which will save you a few keystrokes compared to the sequence you came up with:
NSMakePoint(self.bounds.size.width, baselinePosition)
You'll notice that the old macros and various constants used in the Cocoa API follow a natural English word order:
NSMakeRect(), NSMakeRange(), etc.
and for the options (e.g., in NSString)
NSAnchoredSearch, NSNumericSearch, NSCaseInsensitiveSearch, etc.
The concept that these options have in common ("search") is added to the end of the symbol name, as was the convention when the NSString class was designed.
The more modern APIs use a naming convention so names that belong to the same "group" begin with the same word(s). This makes it easier to alphabetize and greatly helps the autocomplete suggest the possible options for a parameter value. You can see this in NSOperation, for instance.

New Objective-c Literals in 4.4

I can write #42, which creates an NSNumber with int value 42. Can I do this with a variable, like #someIntVar? Obviously I tried it and it doesn't work (which sucks because then I have to go through [NSNumber numberWithInt:someIntVar]). Is it possible with a slightly different syntax?
I strongly suggest you read the official clang documentation on the matter: http://clang.llvm.org/docs/ObjectiveCLiterals.html
But, to box a variable, or any expression, you can use parentheses:
id num = #(someIntVar);