Huge proponent of using the 'var' keyword in C# for cases where it's very clear. For instance, rather than this...
ThisIsMyReallyLongFooClassName foo = new ThisIsMyReallyLongFooClassName();
I can type this...
var foo = new ThisIsMyReallyLongFooClassName();
...and I still have a strongly-typed variable. The two are, for all intents and purposes, equal. The latter is just more readable (again, because it's clear. There are cases where it isn't and 'var' shouldn't be used. I don't want this to become a discussion of that however.)
I'm wondering if Objective-C has anything similar.
Yes and no.
You can use id foo = ... which will always work, but you lose the type information.
If you really want something equivalent, you could use auto foo = ... from C++11, but then you have to compile your file as Objective-C++, which has many other side effects.
Convention is to just spell out your types; it's annoying, but unlike C++, C#, Java where templates/generics can make typenames very long, it's usually manageable in Objective-C.
There is now, __auto_type. For example...
__auto_type test = #"Hello World";
...results in test having the type NSString*.
Here's a decent writeup:
https://medium.com/#maicki/type-inference-with-auto-type-55a38ef56372
The author suggests using
#define let __auto_type const
#define var __auto_type
in some shared header in your application to make the usage cleaner. I'm a bit wary of this kind of macro usage personally but I've been doing it for a while and the world is still turning... Maybe macro names less likely to cause a collision would be better.
No, there is no equivalent in Objective C. C++11 introduced the auto keyword to do it, but neither C nor Objective C has a similar capability.
The id is closest to C#'s dynamic keyword. It lets you achieve similar results to var, except that it does not let you access properties using the property syntax. It does let you invoke methods, including methods that implement property accessors.
You can do something like this:
__typeof([obj someMethod]) foo = [obj someMethod];
That's ugly, but if you have a snippet or macro defined to automatically generate it, then you don't have to type out the type names. For example:
#define LET(V, EXPR) __typeof(EXPR) V = (EXPR)
LET(vc, self.viewController); // equivalent to "UIViewController* vc = self.viewController;"
LET(d, [number doubleValue]); // equivalent to "double d = [number doubleValue];"
LET(foo, [[Foo alloc] init]); // equivalent to "Foo *foo = [[Foo alloc] init];"
Note: I'm not recommending this approach, as the convention in Objective-C is to write out the full type names or use id, and macros can be messy. But knowing about __typeof() can be handy.
There is the id keyword in Objective-C, but note that it is equivalent to the dynamic keyword in C# and not the var keyword. var is implicit typing - ie the type is inferred, but it is still static typing. dynamic and id are for dynamic typing and you lose type information.
I am afraid that no such equivalent exists in Objective C which would allow you to preserve strong typing.
You can use id keyword in objective C, but it doesn't work as c#
in c#
var stringVar = ...
stringVar worked as string variable and you can use access the string function by doing stringVar.function
id stringVar = [NSString ...]
but it still work as normal id type.
Related
I'm trying to learn how to develop using objective C and I read on this book that to access an ivar from a class using dot syntax (obj.var) you must implement these vars using #properties, however I've tried using this kind of access without defining #properties for these vars and it seemed to work normally.
How does this kind of access works ? Is it a good practice to use it like it's in Java ?
Example:
ComplexNumber *c1 = [[ComplexNumber alloc]init];
c1.realPart = 3;
c1.imaginaryPart = 2;
ComplexNumber's methods:
- (double)modulus;
-(void)setRadius:(double)aRadius phase:(double)aPhase;
-(void)print;
-(double)realPart;
-(double)imaginaryPart;
-(void)setRealPart:(double)value;
-(void)setImaginaryPart:(double)value;
A property is just a promise that the class implements certain methods. The dot syntax is simply translated into calls to methods with the appropriate name, depending on what the code is doing:
b = a.foo; // becomes 'b = [a foo];'
a.foo = b; // becomes '[a setFoo:b];'
So you can actually get away with using dot syntax to call methods even when those methods aren't properties. That can be sort-of okay if the method represents something that works like a property, such as accessing the length method of an array:
len = myArray.length // becomes 'len = [myArray length];'
But mostly you shouldn't do it. It takes something that's not a property and makes it look like a property. It might work, but it's going to confuse people who look at the code (including the future you). You definitely shouldn't use it to call methods that have side effects because property accessors aren't expected to have side effects.
No its not a good practice, you technically can access zero argument methods using dot syntax but now Xcode will warn you about doing this. This is against Apple's coding guidelines.
Bracket syntax should be used for calling methods.
What's the difference between the variable declarations:
//version 1
MyClass* myVar = [[MyClass alloc] init];
//version 2
MyClass * myVar = [[MyClass alloc] init];
//version 3
MyClass *myVar = [[MyClass alloc] init];
what changes will occur with the object myVar for each version?
Purely stylistic, no difference. In C, developers tend to prefer the latter style, probably for the simple reason that it makes declaring multiple pointers clearer:
int *ptr1, *ptr2;
...
It's also the style of the original, popular authors when C came out like Kernighan and Ritchie's C Programming Language. Dennis Ritchie, by the way, created C.
However, a lot of modern C++ developers, including Stroustrup himself (creator of C++), tend to favor that first convention:
int* ptr = ...;
The rationale for that preference probably comes down to a couple of things:
In C++, we have templates which require us to specify types on their own. vector<int*> seems a bit more straightforward about emphasizing int* as a single type rather than vector<int *> or some other variant.
When adhering to C++ coding standards which are intended to promote safe designs, we don't find ourselves wanting to define multiple variables at once so often since we generally want to define them when they can be meaningfully initialized (avoiding potential errors by limiting scope and immediately initializing them). *
This is quite different from C where every variable is required to be declared at the top of the scope which causes many C developers to have the frequent habit of declaring multiple at a time.
There is no difference between any of the declarations MyClass* myVar, MyClass * myVar or MyClass *myVar: it is a programmer preference.
Many programmers prefer MyClass *myVar, as it prevents making the following simple mistake (if the programmer intended to declare two pointers to MyClass):
MyClass* myVar, myVar2;
where myVar2 is not a MyClass*, but a MyClass.
There is no semantic difference between your three suggestions.
Essentially, When a code file is parsed, the preprocessor splits everything into tokens, and all later passes of the compilation process works exclusively on these tokens. Thus, spacing
between the tokens is completely ignored.
The syntax for a simple pointer declaration (with a single element being declared and without initialization) consists of three tokens: a type specifier, an asterisk (which denotes that the variable is a pointer) and, finally, an identifier. Thus, you can have any amount of whitespaces between these three, without changing the semantics at all.
The reason people choose one way over another has to do with style and what it expresses about intent.
MyClass* myVar makes it clear that the type of myVar is MyClass.
MyClass *myVar makes it clear that the pointer token belongs to the myVar variable.
The second alternative is thus especially recommended if you decide to declare a list of variables in a single statement. Such as MyClass myVar, *myPointerToVar.
Another good alternative is to always use the MyClass* myVar variant, and never make a declaration listing several variables where some are pointers.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Operator overloading in C
If I have a struct:
typedef struct myStruct {
...
} myStruct;
myStruct myStructAdd(myStruct a, myStruct b);
I need something like this:
#define myStruct a + myStruct b myStructAdd(a, b)
// NOTE this code does NOT WORK. This is what the question is asking.
To make this syntax valid:
myStruct a;
myStruct b;
myStruct c = a + b;
Is there any way to use a #define to do this?
EDIT:
I'm not asking for alternatives to the + syntax. What I'm asking is if, and how, the preprocessor can be used to rewrite the plus syntax to standard C syntax on compile.
i.e. something like #define myStruct a + myStruct b myStructAdd(a, b) which turns myStructA + myStructB into myStructAdd(myStructA, myStructB) on compile.
Operator overloading simply isn't a feature of C or Objective-C. C++ allows you to define arbitrary behaviour for operators and custom types. In Objective-C, if two objects can be added together, then usually there is a method for that:
Foo *result = [foo1 fooByAddingFoo:foo2];
Or, if the class is mutable:
Foo *foo1 = [Foo fooWithBar:bar];
[foo1 addFoo:foo2];
If operator overloading is a must-have feature, use C++ instead, or use Objective-C++ (but keep in mind that C++ classes and Objective-C objects are totally and fundamentally different).
Edit:
The C proprocessor is conceptually very simple, and it knows very, very little about C's syntax, and nothing at all about C's types. If you wanted to overload an operator using the preprocessor, then it would have to learn every type (including custom types) used in your code, and it would have to perform static type checking in order to determine which function to invoke, and this is something that is way out of the scope of the preprocessor.
It's an interesting idea, but it's simply not possible.
There is no way for you to do that using the preprocessor. Also, as far as I known, there is no other feature that would provide this in objective C.
However, if you would use C++ (or objective-C++, which give you all features of both Objective C and C++) you could define an operator+, as follows:
struct myStruct
{
myStruct operator+(myStruct const & other)
{
return ...;
}
}
If you limit your question to the preprocessor then the answer is that it is impossible due to the fact that to define a macro that takes in arguments you have to have a parentheses macro like
#define __DO_STH(par1,par2)
Operator overloading the way you think of it does not use parentheses so you can not create any such macros
The only way to do that would be to make a simple parser which would be reading your code and whenever it encountered the structs you need being added with a plus sign spit out C code that replaces that with the function, but why do that and not use C++ where it's natively supported?
Also unless you are asking for purely academic purposes, it is my honest opinion that operator overloading always does more bad than good and is better avoided.
The only way I know is to use Objective-C++. To do this, give your implementation file the extension "mm" and you're good to go.
I've seen this operator pop up quite a few times in example code in "Learn Objective C on the Mac."
I believe it's an operator in the C language which Objective C inherits.
I tried Googling and searching Stack Overflow and oddly nothing came up.
Does it have an English name?
It has to do with structures.
When we have a struct available locally on the stack, we access its members with the . operator. For example:
CGPoint p = CGPointMake(42,42);
NSLog(#"%f", p.x);
However, if we instead have a pointer to a structure, we have to use the -> operator:
CGPoint *p = malloc(1*sizeof(CGPoint));
p->x = 42.0f;
NSLog(#"%f", p->x);
free(p);
-> is not specific to Objective-C. It's a C operator.
Now that's cleared, it's the member access operator, equivalent to a pointer dereference and then using the dot operator on the result.
Say you had a struct like this:
typedef struct Person {
char *name;
} Person;
Person *jacob = malloc(1*sizeof(Person));
So this statement:
jacob->name = "Jacob";
Is equivalent to this statement:
(*jacob).name = "Jacob";
Of course, don't forget the free:
free(jacob);
In C
a->b
is a shortcut for
(*a).b
which is for dereferencing of members of a struct that is pointed to.
This is useful, because of . binds stronger than the dereferencing operator * . So by using -> you avoid having to use these ugly parentheses.
It's a member selection (or access) equivalent to a pointer de-reference (as pointed out in comments)
a->member is equivalent to (*a).member in C/C++
The same thing that it means in C. It can be used to access the instance variables of objects directly, but generally this is not the best practice. The dot notation you're referring to is a property, not the usual C dot notation.
It's the "indirect member access operator". It's a C operator, which both Objective-C and C++ inherited.
This
a->b
is equivalent to:
(*a).b
but is less typing. (The parens are necessary in the expanded form due to precedence of * and ..)
a->b is equivalent to (*a).b, and designates member b of the object pointed to by a.
In the C standard, it is called the "structure/union pointer operator," which isn't really the catchiest name.
It's all been said, it is a shortcut for accessing members of a struct pointer, but just a note to add that you can access ivars using the same syntax due to the way the Objective-C runtime works:
#interface Foo : NSObject {
NSString *something;
}
/* ... SNIP ... */
NSLog(#"something = %#", foo->something); // Where foo is an instance of the Foo class
This is handy when you need to access ivars that aren't exposed by methods; specifically when you need to implement copyWithZone: on your objects.
i am viewing this video on objective c. the guy show a method which takes multiple arguments and it looks like this
- (void) setTo: (int) n over: (int) d
{ .... }
to use it he shows:
[myFraction setTo: 100 over:200];
how would that bracket notation look in dot noation? andi dont understand what that over
means, would anyone know? thnx
The dot notation is a shorthand notation for property access only. The compiler translates it to the appropriate setter/getter method call. It is just syntactic sugar.
So given this property access using dot notation:
myFraction.numerator=100;
The compiler replaces it with the following equivalent code:
[myFraction setNumerator:100]
Now it should be clear why you cannot use dot notation for sending a normal message to an object. I can't even think of a way how that should even look like.
There is a lot of discussion concerning dot vs. bracket notation going on. One of the arguments against dot notation is the confusion it generates especially for beginners. Other languages do of course use methods for property accessors too, however they hide this fact more consistently than Objective-C.
You cannot pass multiple arguments with dot notations. A setter usable by dot-notation must have the prototype
-(void)setXxxx:(type)value;
However, you can create an auxiliary struct to group all arguments into one:
struct Fraction { int n, d; };
struct Fraction MakeFraction(int n, int d) {
struct Fraction r;
r.n = n;
r.d = d;
return r;
}
...
-(void)setValue:(struct Fraction)f { ... }
...
myFraction.value = MakeFraction(100, 200);
(and a "over" b means a / b.)
From the looks of it, this method is setting two instance variables/properties of the object the numerator (n) and the denominator (d). You cannot do this using dot notation unless you break it into two calls:
myFraction.numerator=100;
myFraction.denominator=200;
Note that dot notation is only for accessing instance variables/properties and not an alternative to message sending.
In Objective-C, we can name methods with arguments in the middle. So when he writes [myFraction setTo:100 over:200];, the over could mean... well, whatever he wants. It's part of the method name he chose. In this case, he was probably trying to make the method sound like English. ("Set this fraction to 100 over 200." We read fractions as "numerator over denominator" often in normal speech.)
Some methods, called "accessors", we write very frequently: these are methods of the form - (int)variable (called "getters"), and - (void)setVariable:(int)newValue (called "setters"). My examples here would assumedly return, or change, respectively, an instance variable called variable. Here's what the method implementations might look like:
- (int)variable
{
return variable;
}
- (void)setVariable:(int)newValue
{
variable = newValue;
}
It's common to have accessors like this for almost every instance variable your class has. At some point, someone got tired of writing [myInstance setVariable:20]; and such, and decided they'd rather it look like many other languages out there, myInstance.variable = 20;.
Therefore, Objective-C 2.0 added dot notation, which allows you to write...
myInstance.variable, which is exactly equivalent to [myInstance variable] in most circumstances (and does NOT access the instance variable variable directly!), and...
the special case myInstance.variable = 20;, which is exactly equivalent to [myInstance setVariable:20];. Again, note that this does not access variable directly, it sends a message to myInstance. So if we'd written some other code in setVariable, it would still be accessed if we used dot notation.
Dot notation is designed to be used for accessors. You could also theoretically use it for any method that returns a value and takes no arguments (myArray.count, for example). Using it for anything else (myInstance.doSomeAction) is extremely poor style. Don't do it. Therefore, as I'm sure you can guess by now, [myFraction setTo:100 over:200] has no dot notation equivalent, as it takes 2 arguments, and isn't an accessor.
[myFraction numerator]
Could be written as
myFraction.numerator
but you can also assign values such as
instance.property = value
But you cannot pass multiple arguments in dot notation.