NSArray objectAtIndex: shorthand [duplicate] - ios

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is there some literal dictionary or array syntax in Objective-C?
I have recently noticed that something strange seems to work in objective-c.
When I have an array,
NSArray *myArray = #[#"1", #"b", #"3", #"d"];
I can normally access the second element by,
NSString *element = [myArray objectAtIndex:1]; // second element
however I seem to now also be able to access it via.
NSString *element = myArray[1];
Does anyone know if this is now a defined behaviour and therefore safe to use, or should I avoid it? Thanks to anyone who can help!!

This syntax was added in Clang 3.3 : Objective C Literals. Essentially, the compiler converts expressions of the type objCObj[idx] to the expression [objCObj objectAtIndexedSubscript:idx]. It also works for dictionaries, and you're free to adopt it for your own objects.
As such, you're perfectly safe using it, assuming you'll be using a modern version of Objective C and suitably updated Objective C compiler (i.e. Clang).

this is a new feature of objective-c and avaiable since xCode 4.5
its safe to use this syntax, you can even give your own classes support for this.

Ya, it's safe to use these syntax.
Those syntax are part of Modern Objective-C.
You can check this article for more options: ObjectiveCLiterals

It's a perfectly valid code for the latest version of the LLVM compiler.
So far, it's invalid for other compilers (e.g. GCC).
Whether you should avoid it or not - well, it's a matter of taste. There are several big discussions about it on the internet since the indexing behaves slightly different (a whole different method is used to implement it).
There are also discussions whether to use the expression literals or not since there are ocassions when they are making the code less readable (e.g. they are written like literals but they actually are autoreleased objects). Note that everything is done using literals can be done using simple macros.

Related

Any way to highlight operators comparison for Objects in iOS Objective-C project

Recently in a iOS project I have refactored money data type from double to NSDecimalNumber to get a rid of discrepancies caused by handling money with doubles.
The refactoring is complete but my concerns are for all those comparisons made through standard operators that are not raised as errors by the compiler because comparing objects is still valid (memory addresses are compared) but not logically correct
double a = 4;
double b = 3;
if(a > b) do stuff //valid and logically correct
NSDecimalNumber *a = [NSDecimalNumber decimalNumberWithString:#"4"];
NSDecimalNumber *b = [NSDecimalNumber decimalNumberWithString:#"3"];
if(a > b) do stuff //valid but not logically correct as here the memory addresses of variables will be compared instead of values.
Is there any way to make the compiler highlight these situations?
My first idea was to create a category for NSDecimalNumber and overloading operators so that they would work properly for them and, as it s not possible to override operators in Obj-C, I tried 2 different ways to accomplish this:
Creating a swift extension of NSDecimalNumber where I overload those operators (in swift it s possible to override standard operators) and then using those new methods in my Obj-c environment through Swift bridge. After some tests and have red a lot on StackOverflow it seems this approach is not possible as Obj-C will always treat standard operators in the common way (comparing addressed for objects)
Creating a category for NSDecimalNumber where I overload those operators though C++ that gives the option to overload operators to the programmer. The problem here is that I am not confident with C++ and I cannot find any example to address me.
So in the end I need a way to highlight any comparison between objects made with standard operators.
Any help is really appreciated,
Thanks.

objective-c creates array with ellipse

I am extremely new to Objective-C and iOS programming. The tutorial I am using has the following syntax for creating a NSString array representing the ranks of a deck of cards. My question is whether it is valid:
NSArray *rankStrings =#[#"?",#"A",#"2",#"3",...,#"10",#"J",#"Q",#"K"];
The reason for the question is that xCode is giving a red exclamation mark which says Expected expression. I don't want to mis-learn that ellipses are unacceptable. So I am asking here to know exactly why I am getting the error.
For comparison, python has range functions for creating lists. So maybe the ellipse here is comparable: I don't know. So can someone point out what's wrong with the declaration? Whether it is the ellipse, or how I am using them, or something else?
Just replace
NSArray *rankStrings =#[#"?",#"A",#"2",#"3",...,#"10",#"J",#"Q",#"K"];
with
NSArray *rankStrings =#[#"?",#"A",#"2",#"3",#"4",#"5",#"6",#"7",#"8",#"9",#"10",#"J",#"Q",#"K"];
Objective-C can not continue the array for you on it's own. The book author was just a little too laze to continue so he inserted the ...
Something like the Python's advanced slicing operation using an ellipsis does not exist in Objective-C.
Your code
NSArray *rankStrings = #[#"?",#"A",#"2",#"3",...,#"10",#"J",#"Q",#"K"];
is invalid.
Can you please post more about your code?
and you are using
NSArray * #[objects ....]
and I am sure your Array
NSArray *rankStrings =#[#"?",#"A",#"2",#"3",...,#"10",#"J",#"Q",#"K"];
is right.

Class method access by dot operator [duplicate]

This question already has answers here:
Objective-C dot notation with class methods?
(3 answers)
Closed 9 years ago.
This question related to knowing something we don't know. I'm researching with "Why people don't use this"? Is any reason behind this related to specific tech? So read it carefully and give downvote or give correct answer.
We can write
NSMutableString *string = NSMutableString.string;
instead of
NSMutableString *string = [NSMutableString string];
Same as how can we write this method,
NSMutableString *string = [NSMutableString stringWithString:#"test"];
Update:
This question is not an duplicate which is little bit different. And I accept with below answers which is not recommended for good programmers. But They didn't explain Why, for What reason, programmers should avoid this? Could anyone give clear explanation about this with proper link or document?
NSMutableString.string is a hack. It "works" for the same reason that myString.length and [myString length] produce the same result. However, since dot notation is not used with an actual property, it is an abuse of the language feature, because properties have a different semantic. For example, when you access a property multiple times, you naturally expect to get the same result, unless the state of the object has changed in between the two invocations. Since NSMutableString.string produces a new string object on each invocation, it breaks the semantic expected of the "proper" properties, bringing down the readability of your program.
Objective-C does not have a general way of calling a method with arguments using the dot notation. There feature is very specific to properties. Although theoretically you could use MyClass.xyz = abc in place of [MyClass setXyz:abc], but that would be a hack as well.
To answer your question, Objective-C does not offer a way to call [NSMutableString stringWithString:#"test"] with dot notation.
It's just a syntactic sugar. string method has no arguments so it's treated like a getter, which is not in fact. stringWithString: is method with parameter, so you can't call like that.
In general, I'd not recommend using dot syntax with methods, it's confusing.
Objective-C dot notation with class methods?
Update
I don't think there is any technical reason you should avoid it.
It's rather in means of coding style, keeping code clean and consistent.

How are these NSArray initialization methods different? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
NSArray initialization methods
What is the difference between initializing array with
NSArray * array = [NSArray array];
and
NSArray * array = #[];
The two expressions are generally equivalent.
Clang's documentation lists a caveat for object literals:
Objects created using the literal or boxed expression syntax are not guaranteed to be uniqued by the runtime, but nor are they guaranteed to be newly-allocated. As such, the result of performing direct comparisons against the location of an object literal (using ==, !=, <, <=, >, or >=) is not well-defined. This is usually a simple mistake in code that intended to call the isEqual: method (or the compare: method).
As the documentation states, the caveat listed above only occurs when using direct comparison operators between objects, which is almost always not the intended action anyway. This behavior shouldn't matter, so the two can almost always be used interchangeably.
The #[] is the shortcut for [NSArray array] in modern Objective C
Please check The_Basics_of_Modern_Objective-C for a better understanding.
In my knowledge when you use the #[] this will be equivalent to the corresponding Class methods. Means:
#[] = [NSArray array];
#[#"M",#"P"] = [NSArray arrayWithObjects:#"M",#"P",nil];
These both are similar.
[NSArray array] and #[] creates and returns an empty array.
#[] is an new feature added in Objective-C. It boxes several kind of objects, and gives you flexibility of shortcut notation.
When using Apple LLVM compiler 4.0 or later, arrays, dictionaries, and
numbers (NSArray, NSDictionary, NSNumber classes) can be created using
literal syntax instead of methods. Literal syntax uses the # symbol
combined with [], {}, (), to create the classes mentioned above,
respectively.
More references Here, Literals

Obj-c for..in loop with NSArray ordering? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Does fast enumeration in Objective-C guarantee the order of iteration?
Just a quick question that was proving problematic to google:
When fast-iterating over an NSArray like so:
for (NSObject *obj in array) {}
Is the order well-defined? In my tests it seems to be, but I wasn't able to find a guarantee anywhere...
Thanks!
From the Fast Enumeration section of The Objective-C Programming Language:
For collections or enumerators that have a well-defined order—such as an NSArray or an NSEnumerator instance derived from an array—the enumeration proceeds in that order, so simply counting iterations gives you the proper index into the collection if you need it.
Yes, it does.
The documentation says NSArray and its subclasses «manage ordered collections of objects».
This is the guarantee you are looking for.
Note this is not the case with NSDictionary, for instance.

Resources