I am just starting climbing the Objective C learning curve (using Nerd Ranch iOS programming book).
Based on what I have know from other languages about "nesting" multiple executions within one line I assumed that I can alter:
NSString* descriptionString = [[NSString alloc] initWithFormat:#"%#", possesionName]
with a two line version:
NSString* descriptionString = [NSString alloc];
[descriptionString initWithFormat:#"%#", possesionName]
but it seems that the second attempt raises an exception
2012-01-22 18:25:09.753 RandomPossessions[4183:707] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -length only defined for abstract class. Define -[NSPlaceholderString length]!'
Could someone help me understand what exactly I am doing wrong here? Thanks a lot in advance.
PS. If this is a way Objective C messages work and you have to make alloc and init in one line just let me know - I assumed this is just a set of functions that either can be executed two in one go or one after another.
An important difference between both versions (they are not exactly equal) is that in the first version you use the result of initWithFormat for the variable descriptionString, while you use the result of alloc in the second. If you change your code to
NSString* descriptionString = [NSString alloc];
descriptionString = [descriptionString initWithFormat:#"%#", possesionName]
all should be well again. It is specified that an object returned by alloc shall not be seen as initialized and functional until some init Method has been called and init might return something else.
The alloc method will allocate memory for a new object. But the init method might throw away that memory and return a completely different object. Or it might return nil. This is why you must always do self = [super init] when you override an init method.
NSString is one class that does this kind of thing all the time.
I'm not exactly sure why the exception is happening, but I believe it could be ARC injecting code in between your two lines of code or something similar. Whatever it is, something is trying to act on the allocated object that has never been initialised, and this is a huge problem that can lead to all kinds of issues. Consider yourself lucky it threw an exception, sometimes it wont.
The NSString class might not actually be a real class. It may contain almost no methods and almost no variables. All it has is a bunch of factory methods to create "real" string objects of some other class, and this is done using methods like initWithFormat:. So, by long standing convention alloc/init must always be done in a single statement and there are a handful of places where, usually for performance reasons, something will rely on this convention being used.
Basically, objective-c is a language where you don't need to know exactly what is going on inside an object. You just need to know what messages can be sent to an object, and how it will respond. Anything else is undefined behaviour and even if you learn how it works, it is subject to change without notice. Sometimes the behaviour will change depending on circumstances that are completely illogical, for example you might expect the "copy" method to give you a copy of the object you send it to, and while this is the default behaviour, there are many cases where it will actually just return the same object with slightly different memory management flags. This is because the internal logic of the class knows that returning the same object is much faster and effectively identical to returning an actual copy.
My understanding is copy sent to NSString may return a new object, or it may return itself. It depends on which NSString subclass is actually being used, and there isn't even any documentation for what subclasses exist, let alone how they're implemented. All you need to know, is that copy will return a pointer to an object that is perfectly safe to treat as if it was a copy even though it might not be.
In a "proper" object oriented language like Objective-C, objects are "black boxes" which can intelligently change their internal behaviour at any time for any reason, but their external behaviour always remains the same.
With regard to avoiding nesting... The coding style for Objective-C often does require extensive nesting, or else you'll be writing 10 lines of code when only 1 is really needed. The square brace syntax is particularly suited to nesting without making your code messy.
As a rule of thumb, I turn on Xcode's "Page Guide at column" feature, and set it to 120 characters. If the line of code exceeds that width then I'll think about breaking it into multiple lines. But often it's cleaner to have a really long line than three short lines.
Be pragmatic about it. :)
From Apple's library reference, initWithFormat:
Returns an NSString object initialized by converting given data into Unicode characters using a given encoding.
So you can use these two lines of code:
NSString* descriptionString = [NSString alloc];
descriptionString = [descriptionString initWithFormat:#"%#", possesionName];
For more info please go to:
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html#//apple_ref/occ/instm/NSString/initWithFormat:
What is better and why ?
What is better in such situations as the class init method and usual variables in a code ?
What is better and why ?
Explicit typing information is always better unless you just can't use it for some reason (see below).
It allows the compiler to much more stringently validate the code and will catch many errors at compile time that would otherwise cause your app to crash at runtime.
A long, long, time ago, everything in the APIs used id. This proved to be a complete pain in the butt; fragile and led to many crashes that would have been caught with specific types.
So, it was changed. (This was ~1994).
What is better in such situations as
the class init method and usual
variables in a code ?
For init, you have no choice but to use the generic (id) return type. Objective-C does not support either co-variant or contra-variant declarations, nor is there a mechanism for generalizing the declaration of init while also providing support for specific type checking.
Same goes for retain, objectAtIndex:, addObject: and many other methods that take or return one of many kinds of objects (or take 'em as arguments).
And, no, there is absolutely no performance difference whatsoever between id and, say, NSView*.
can you give an example when explicit
typing will cause a problem please?
If you wrote:
- (MyClass *) init;
And in a subclass:
- (MySubclass *) init;
You'd get compiler warnings out the wazoo most likely or you'd have to typecast out the wazoo.
On recent versions of clang (in Lion) you should actually not return id, and instead return instancetype. This is a keyword that is used in return types to specify that the type it returns is an instance of the class receiving the message. It is now the preferred return type for init methods on OS X Lion.
Explicit typing provides build-time protection, informing you of likely problems if you do things such as casting or performing operations on something that probably won't work.
Explicit typing also helps prevent non-obvious transfer of mistyped objects, something traveling through a path in your code you hadn't considered that turns out to be of an unexpected type. This kind of bug often doesn't become clear until the program has been tested a lot, more commonly after its release.
It's also helpful for future programmers (including your future self) trying to work with your code, making to more likely that they'll be able to tell at glance what an object is supposed to be. It makes code more "self-documenting" as a result.
Some things cannot have a meaningful type because no type actually applies. Other times you need to use id because you need to be able to accept any type of object. Cocoa Touch uses it, for example, when referring to the sender of a message because anything could have sent it; specifying an explicit type simply wouldn't work.
The vast majority of the time, though, an explicit type is to your advantage.
Use a type as specific as you can but not more so. Consider how you are using any particular variable, argument, or return type and set its type appropriately.
For example a UITableView's dataSource property is declared as id<UITableViewDataSource> because the table view only cares that its data source is some object which conforms to the UITableViewDataSource protocol. This allows the data source to be flexible enough for use with any specific class which implements the protocol but still allows the compiler to warn you if you attempt to assign an object which does not implement that protocol as the data source.
If you are too specific then your code becomes inflexible, accepting only specific implementations which are not strictly necessary (ie demanding a NSMutableString when you could really work with any NSString).
If you are too vague (typing everything as id for example) then you lose the ability to identify when you are sending unrecognized selectors to a particular instance and the compiler cannot identify any number of invalid statements.
For init methods follow the advice in The Objective-C Programming Language
The return type of an initializer method should be id.
The reason for this is that id gives an indication that the class is purposefully not considered—that the class is unspecified and subject to change, depending on context of invocation. For example, NSString provides a method initWithFormat:. When sent to an instance of NSMutableString (a subclass of NSString), however, the message returns an instance of NSMutableString, not NSString. (See also, though, the singleton example given in “Combining Allocation and Initialization.”)
I don't think there is a performance difference between both.
You can let id return type for init because you can cast the result of your init.
For exemple :
Toto *foo = [[Toto alloc] init];
id foo2 = [[Toto alloc] init];
Both work but you'll have to cast foo2 variable like that (Toto *)foo in order to access property or methods of your instance without creating a compiler warning. Even if it works fine...
I think some developers let id because they just pass there variable trough instance and don't use it. That kind of use allow to not import the .h
Regards,
KL94
In Objective-C, you can't declare method names where the last component doesn't take an argument. For example, the following is illegal.
-(void)take:(id)theMoney andRun;
-(void)take:(id)yourMedicine andDontComplain;
Why was Objective-C designed this way? Was it just an artifact of Smalltalk that no one saw a need to be rid of?
This limitation makes sense in Smalltalk, since Smalltalk doesn't have delimiters around message invocation, so the final component would be interpreted as a unary message to the last argument. For example, BillyAndBobby take:'$100' andRun would be parsed as BillyAndBobby take:('$100' andRun). This doesn't matter in Objective-C where square brackets are required.
Supporting parameterless selector components wouldn't gain us much in all the usual ways a language is measured, as the method name a programmer picks (e.g. runWith: rather than take:andRun) doesn't affect the functional semantics of a program, nor the expressiveness of the language. Indeed, a program with parameterless components is alpha equivalent to one without. I'm thus not interested in answers that state such a feature isn't necessary (unless that was the stated reasons of the Objective-C designers; does anyone happen to know Brad Cox or Tom Love? Are they here?) or that say how to write method names so the feature isn't needed. The primary benefit is readability and writability (which is like readability, only... you know), as it would mean you could write method names that even more closely resemble natural language sentences. The likes of -(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)theApplication (which Matt Gallagher points out on "Cocoa With Love" is a little bit confusing when you drop the formal parameter) could be named -(BOOL)application:(NSApplication*)theApplication shouldTerminateAfterLastWindowClosed, thus placing the parameter immediately next to the appropriate noun.
Apple's Objective-C runtime (for example) is perfectly capable of handling these kind of selectors, so why not the compiler? Why not support them in method names as well?
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#interface Potrzebie : NSObject
-(void)take:(id)thing;
#end
#implementation Potrzebie
+(void)initialize {
SEL take_andRun = NSSelectorFromString(#"take:andRun");
IMP take_ = class_getMethodImplementation(self, #selector(take:));
if (take_) {
if (NO == class_addMethod(self, take_andRun, take_, "##:#")) {
NSLog(#"Couldn't add selector '%#' to class %s.",
NSStringFromSelector(take_andRun),
class_getName(self));
}
} else {
NSLog(#"Couldn't find method 'take:'.");
}
}
-(void)take:(id)thing {
NSLog(#"-take: (actually %#) %#",NSStringFromSelector(_cmd), thing);
}
#end
int main() {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
Potrzebie *axolotl=[[Potrzebie alloc] init];
[axolotl take:#"paradichloroaminobenzaldehyde"];
[axolotl performSelector:NSSelectorFromString(#"take:andRun")
withObject:#"$100"];
[axolotl release];
[pool release];
return 0;
}
This is Brad Cox. My original answer misunderstood the question. I assumed reallyFast was a hardcoded extension to trigger faster messaging, not a kind of syntactic sugar. The real answer is that Smalltalk didn't support it, perhaps because its parser couldn't deal with the (assumed) ambiguity. Although OC's square brackets would remove any ambiguity, I simply didn't think of departing from Smalltalk's keyword structure.
21 years of programming Objective-C and this question has never crossed my mind. Given the language design, the compiler is right and the runtime functions are wrong ().
The notion of interleaved arguments with method names has always meant that, if there is at least one argument, the last argument is always the last part of the method invocation syntax.
Without thinking it through terribly much, I'd bet there are some syntactic bugaboos with not enforcing the current pattern. At the least, it would make the compiler harder to write in that any syntax which has optional elements interleaved with expressions is always harder to parse. There might even be an edge case that flat out prevents it. Certainly, Obj-C++ would make it more challenging, but that wasn't integrated with the language until years after the base syntax was already set in stone.
As far as why Objective-C was designed this way, I'd suspect the answer is that the original designers of the language just didn't consider allowing the interleaved syntax to go beyond that last argument.
That is a best guess. I'll ask one of 'em and update my answer when I find out more.
I asked Brad Cox about this and he was very generous in responding in detail (Thanks, Brad!!):
I was focused at that time on
duplicating as much of Smalltalk as
possible in C and doing that as
efficiently as possible. Any spare
cycles went into making ordinary
messaging fast. There was no thought
of a specialized messaging option
("reallyFast?" [bbum: I asked using 'doSomething:withSomething:reallyFast'
as the example]) since ordinary
messages were already as fast as they
could be. This involved hand-tuning
the assembler output of the C
proto-messager, which was such a
portability nightmare that some if not
all of that was later taken out. I do
recall the hand-hacked messager was
very fast; about the cost of two
function calls; one to get into the
messager logic and the rest for doing
method lookups once there.
Static typing enhancements were later
added on top of Smalltalk's pure
dynamic typing by Steve Naroff and
others. I had only limited involvement
in that.
Go read Brad's answer!
Just for your information, the runtime doesn't actually care about the selectors, any C string is valid, you could as well make a selector like that: "==+===+---__--¨¨¨¨¨^::::::" with no argument the runtime will accept it, the compiler just can't or else it's impossible to parse. There are absolutely no sanity check when it comes to selectors.
I assume they are not supported in Objective-C because they weren't available in Smalltalk, either. But that has a different reason than you think: they are not needed. What is needed is support for methods with 0, 1, 2, 3, ... arguments. For every number of arguments, there is already a working syntax to call them. Adding any other syntax would just cause unnecessary confusion.
If you wanted multi-word parameterless selectors, why stop with a single extra word? One might then ask that
[axolotl perform selector: Y with object: Y]
also becomes supported (i.e. that a selector is a sequence of words, some with colon and a parameter, and others not). While this would have been possible, I assume that nobody considered it worthwhile.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 months ago.
Improve this question
We now have the "dot" notation for properties. I've seen various back and forths about the merits of dot notation vs. message notation. To keep the responses untainted I'm not going to respond either way in the question.
What is your thought about dot notation vs. message notation for property accessing?
Please try to keep it focused on Objective-C - my one bias I'll put forth is that Objective-C is Objective-C, so your preference that it be like Java or JavaScript aren't valid.
Valid commentary is to do with technical issues (operation ordering, cast precedence, performance, etc), clarity (structure vs. object nature, both pro and con!), succinctness, etc.
Note, I'm of the school of rigorous quality and readability in code having worked on huge projects where code convention and quality is paramount (the write once read a thousand times paradigm).
Do not use dot for behavior. Use dot to access or set attribute like stuff, typically attributes declared as properties.
x = foo.name; // good
foo.age = 42; // good
y = x.retain; // bad
k.release; // compiler should warn, but some don't. Oops.
v.lockFocusIfCanDraw; /// ooh... no. bad bad bad
For folks new to Objective-C, I would recommend not using the dot for anything but stuff declared as #property. Once you have a feel for the language, do what feels right.
For example, I find the following perfectly natural:
k = anArray.count;
for (NSView *v in myView.subviews) { ... };
You can expect that the clang static analyzer will grow the ability to allow you to check that the dot is being used only for certain patterns or not for certain other patterns.
Let me start off by saying that I started programming in Visual/Real Basic, then moved on to Java, so I'm fairly used to dot syntax. However, when I finally moved to Objective-C and got used to brackets, then saw the introduction of Objective-C 2.0 and its dot syntax, I realized that I really don't like it. (for other languages it's fine, because that's how they roll).
I have three main beefs with dot syntax in Objective-C:
Beef #1: It makes it unclear why you might be getting errors. For example, if I have the line:
something.frame.origin.x = 42;
Then I'll get a compiler error, because something is an object, and you can't use structs of an object as the lvalue of an expression. However, if I have:
something.frame.origin.x = 42;
Then this compiles just fine, because something is a struct itself that has an NSRect member, and I can use it as an lvalue.
If I were adopting this code, I would need to spend some time trying to figure out what something is. Is it a struct? Is it an object? However, when we use the bracket syntax, it's much clearer:
[something setFrame:newFrame];
In this case, there is absolutely no ambiguity if something is an object or not. The introduction of ambiguity is my beef #1.
Beef #2: In C, dot syntax is used to access members of structs, not call methods. Programmers can override the setFoo: and foo methods of an objects, yet still access them via something.foo. In my mind, when I see expressions using dot syntax, I'm expecting them to be a simple assignation into an ivar. This is not always the case. Consider a controller object that mediates an array and a tableview. If I call myController.contentArray = newArray;, I would expect it to be replacing the old array with the new array. However, the original programmer might have overridden setContentArray: to not only set the array, but also reload the tableview. From the line, there's no indication of that behavior. If I were to see [myController setContentArray:newArray];, then I would think "Aha, a method. I need to go see the definition of this method just to make sure I know what it's doing."
So I think my summary of Beef #2 is that you can override the meaning of dot syntax with custom code.
Beef #3: I think it looks bad. As an Objective-C programmer, I'm totally used to bracket syntax, so to be reading along and see lines and lines of beautiful brackets and then to be suddenly broken with foo.name = newName; foo.size = newSize; etc is a bit distracting to me. I realize that some things require dot syntax (C structs), but that's the only time I use them.
Of course, if you're writing code for yourself, then use whatever you're comfortable with. But if you're writing code that you're planning on open sourcing, or you're writing something you don't expect to maintain forever, then I would strong encourage using bracket syntax. This is, of course, just my opinion.
Blog post against dot syntax: https://bignerdranch.com/blog/dot-notation-syntax/
Rebuttal to above post: http://eschatologist.net/blog/?p=226 (with original article in favor of dot syntax: http://eschatologist.net/blog/?p=160)
I'm a new Cocoa/Objective-C developer, and my take on it is this:
I stick to the messaging notation, even though I started with Obj-C 2.0, and even though the dot notation is more familiar feeling (Java is my first language.) My reason for this is pretty simple: I still don't understand exactly why they added the dot notation to the language. To me it seems like an unnecessary, "impure" addition. Although if anyone can explain how it benefits the language, I'd be happy to hear it.
However, I consider this a stylistic choice, and I don't think there is a right or wrong way, as long as it's consistent and readable, just as with any other stylistic choice (like putting your opening curly brace on the same line as the method header or the next line).
Objective-C dot notation is a syntactic sugar that is translated to normal message passing, so under the hood changes nothing and makes no difference at runtime. Dot notation it is absolutely not faster than message passing.
After this needed little preamble here's pros and cons seen by me :
Dot notation pros and cons
pros
readability : dot notation is easier to read than nested brackets massages passing
It simplifies interaction with Attributes and Properties: using dot notation for properties and message notation for methods you can achieve separation of state and behavior at the synthax level
It is possible to use compound assignment operator (1).
using the #property and dot notation the compiler do a lot of work for you, it can generate code for good Memory Management when getting and setting the property; this is why dot notation is suggested by Apple itself official guides.
cons
Dot notation is allowed only for access to a declared #property
Since Objective-C is a layer above standard C(language extension), the dot notation doesn’t really make clear if the accessed entity is a an object or a struct. Often, it looks like you are accessing properties of a struct.
calling a method with the dot notation you lose named parameters readability advantages
when mixed message notation and dot notation seems like you are coding in two different languages
Code Examples :
(1)Compound operator usage code example :
//Use of compound operator on a property of an object
anObject.var += 1;
//This is not possible with standard message notation
[anObject setVar:[anObject var] + 1];
Using the style of a language, consistent with the language itself, is the best advice here. However, this isn't a case of writing functional code in an OO system (or vice versa) and the dot notation is part of the syntax in Objective-C 2.0.
Any system can be misused. The existence of the preprocessor in all C based languages is enough to do really quite weird things; just look at the Obfuscated C Contest if you need to see exactly how weird it can get. Does that mean the preprocessor is automatically bad and that you should never use it?
Using the dot syntax for accessing properties, which have been defined as such in the interface, is open to abuse. The existence of abuse in potentia shouldn't necessarily be the argument against it.
Property access may have side-effects. This is orthogonal to the syntax used to acquire that property. CoreData, delegation, dynamic properties (first+last=full) will all necessarily do some work under the covers. But that would be confusing 'instance variables' with 'properties' of an object. There's no reason why properties should necessarily need to be stored as-is, especially if they can be computed (e.g. length of a String, for example). So whether you use foo.fullName or [foo fullName] there's still going to be dynamic evaluation.
Lastly, the behaviour of the property (when used as an lvalue) is defined by the object itself, like whether a copy is taken or whether it is retained. This makes it easier to change the behaviour later - in the property definition itself - rather than having to re-implement methods. That adds to the flexibility of the approach, with the resulting likelihood of less (implementation) errors occurring. There's still the possibility of choosing the wrong method (i.e. copy instead of retain) but that's an architectural rather than implementation issue.
Ultimately, it boils down to the 'does it look like a struct' question. This is probably the main differentiator in the debates so far; if you have a struct, it works differently than if you have an object. But that's always been true; you can't send a struct a message, and you need to know if it's stack-based or reference/malloc based. There are already mental models which differ in terms of usage ([[CGRect alloc] init] or struct CGRect?). They've never been unified in terms of behaviour; you need to know what you're dealing with in each case. Adding property denotation for objects is very unlikely to confuse any programmer who knows what their data types are; and if they don't, they've got bigger problems.
As for consistency; (Objective-)C is inconsistent within itself. = is used both for assignment and equality, based on lexical position in the source code. * is used for pointers and multiplication. BOOLs are chars, not bytes (or other integer value), despite YES and NO being 1 and 0 respectively. Consistency or purity isn't what the language was designed for; it was about getting things done.
So if you don't want to use it, don't use it. Get it done a different way. If you want to use it, and you understand it, it's fine if you use it. Other languages deal with the concepts of generic data structures (maps/structs) and object types (with properties), often using the same syntax for both despite the fact that one is merely a data structure and the other is a rich object. Programmers in Objective-C should have an equivalent ability to be able to deal with all styles of programming, even if it's not your preferred one.
I've mostly been raised in the Objective-C 2.0 age, and I prefer the dot notation. To me, it allows the simplification of code, instead of having extra brackets, I can just use a dot.
I also like the dot syntax because it makes me really feel like I'm accessing a property of the object, instead of just sending it a message (of course the dot-syntax really does translate into message sending, but for the sake of appearances, the dot feels different). Instead of "calling a getter" by the old syntax, it really feels like I'm directly getting something useful from the object.
Some of the debate around this is concerned with "But we already have dot-syntax, and it's for structs!". And that's true. But (and again, this is just psychological) it basically feels the same to me. Accessing a property of an object using dot-syntax feels the same as accessing a member of a struct, which is more or less the intended effect (in my opinion).
****Edit: As bbum pointed out, you can also use dot-syntax for calling any method on an object (I was unaware of this). So I will say my opinion on dot-syntax is only for dealing with properties of an object, not everyday message sending**
I use it for properties because
for ( Person *person in group.people){ ... }
is a little easier to read than
for ( Person *person in [group people]){ ... }
in the second case readability is interupted by putting your brain into message sending mode, whereas in the first case it is clear you are accessing the people property of the group object.
I will also use it when modifying a collection, for instance:
[group.people addObject:another_person];
is a bit more readable than
[[group people] addObject:another_person];
The emphasis in this case should be in the action of adding an object to the array instead of chaining two messages.
I much prefer the messaging syntax... but just because that is what I learned. Considering a lot of my classes and what not are in Objective-C 1.0 style, I wouldn't want to mix them. I have no real reason besides "what I'm used to" for not using the dot syntax... EXCEPT for this, this drives me INSANE
[myInstance.methodThatReturnsAnObject sendAMessageToIt]
I don't know why, but it really infuriates me, for no good reason. I just think that doing
[[myInstance methodThatReturnsAnObject] sendAMessageToIt]
is more readable. But to each his own!
Honestly, I think it comes down to a matter of style. I personally am against the dot syntax (especially after just finding out that you can use it for method calls and not just reading/writing variables). However, if you are going to use it, I would strong recommend not using it for anything other than accessing and changing variables.
One of the main advantages of object-oriented programming is that there is no direct access to internal state of the objects.
Dot syntax seems to me to be an attempt to make it look and feel as though state is being accessed directly. But in truth, it's just syntactic sugar over the behaviors -foo and -setFoo:. Myself, I prefer to call a spade a spade. Dot syntax helps readability to the extent that code is more succinct, but it doesn't help comprehension because failing to keep in mind that you're really calling -foo and -setFoo: could spell trouble.
Synthesized accessors seem to me to be an attempt to make it easy to write objects in which state is accessed directly. My belief is that this encourages exactly the kind of program design that object-oriented programming was created to avoid.
On balance, I would rather dot syntax and properties had never been introduced. I used to be able to tell people that ObjC is a few clean extensions to C to make it more like Smalltalk, and I don't think that's true any more.
In my opinion, the dot syntax makes Objective-C less Smalltalk-esque. It can make code look simpler, but adds ambiguity. Is it a struct, union, or object?
Many people seems to be mixing up 'properties' with 'instance variables'.
The point of the properties is to make it possible to modify the object without having to know its internals, I think. The instance variable is, most of the time, the 'implementation' of a property (which in turn is the 'interface'), but not always: sometimes a property does not correspond to an ivar, and instead it calculates a return value 'on the fly'.
That's why I believe the idea that "the dot syntax tricks you into thinking you're accessing the variable so it's confusing" is wrong. Dot or bracket, you shouldn't make assumptions about the internals: it's a Property, not an ivar.
I think I might switch to messaging instead of dot notation because in my head object.instanceVar is just instanceVar that belongs to object, to me it doesn't look at all like a method call, which it is, so there could be things going on in your accessor and whether you use instanceVar or self.instanceVar could have much more of a difference than simply implicit vs. explicit. Just my 2¢.
The dot notation tries to make messages look like accesses to a member of a struct, which they are not. Might work fine in some cases. But soon someone will come up with something like this:
NSView *myView = ...;
myView.frame.size.width = newWidth;
Looks fine. But is not. It's the same as
[myView frame].size.width = newWidth;
which doesn’t work. The compiler accepts the first, but rightfully not the second. And even if it emitted an error or warning for the first this is just confusing.
Call me lazy but if I had to type a single '.' vs. two [ ] each time to get the same results I would prefer a single . I hate verbose languages. The () in lisp drove me nuts. Elegant language such as mathematics are concise and effective, all others fall short.
Use dot notation (whenever you can)
On instance methods returning some value
Do not use dot notation
On instance methods returning void, on init methods or on Class method.
And my personal favorite exception
NSMutableArray * array = #[].mutableCopy;
I personally don't use dot-notation at all in code. I only use it in CoreData KVC binding expression when required.
The reason for not using them in code for me is that the dot-notation hides the setter semantics. Setting a property in dot-notation always looks like assignment regardless of the setter semantics (assign/retain/copy). Using the message-notation makes it visible that the receiving object has control over what happens in the setter and underlines the fact the those effects need to be considered.
I'm still considering whether I might want to use dot-notation when retrieving the value of a KVC compliant or declared property because it admittedly is a bit more compact and readable and there are no hidden semantics. Right now I'm sticking with message-notation for sake of consistency.
OK, dot notation in Objective-C looks strange, indeed. But I still can't do the following without it:
int width = self.frame.size.width;
Works fine, but:
int height = [[[self frame] size] height];
Gives me "Cannot convert to a pointer type". I'd really like to keep my code looking consistent with message notation, though.
This is a great question and I see many different answers to this. Although many have touched upon the topics, I will try to answer this from a different angle (some might have done it implicitly):
If we use the 'dot' notation, the resolution of the target for the method is done at compile time. If we use message passing, the resolution of the target is deferred to run-time execution. If the targets are resolved at compile time, the execution is faster, since resolving the targets at the run-time includes a few overheads. (Not that the time difference will matter much). Since we have defined the property in the interface of the object already, there is no point in differing the resolution of the target for a property to run-time and hence dot-notation is the notation that we should use for accessing property.