Dot vs arrow notation in Objective-C for non structs - ios7

I've seen examples of arrow notation used for structs. In one tutorial, I saw this syntax in a view controller implementation file:
self->webView.canGoBack) backButton.enabled = YES;
I have no idea why they did not use dot notation. No explanation was given. I tried this in a simple project that has a button and text field. Below is what I put in the button press method:
//header file
#property (strong, nonatomic) IBOutlet UITextField *myInputField;
//implementation file
self.myInputField.text = #"another test";
//self->_myInputField.text = #"text field test";
Either line of code works without issue. So why use one of the above lines over the other?
Also, notice that the arrow notation produces _myInputField.text. What is the significance of the underscore?

In Objective-C, objects are also c structs. If you're new to the language, that knowledge will get you in more trouble than it will help. But it helps explain what you're seeing.
An Objective-C property is a helpful construct that creates an ivar in the object (a new field in the class's struct) that defaults to the property name prefixed by an underscore. A property will also create getter and setter methods, e.g. - (UITextFeild *)myInputField and - (void)setMyInfputField.
Dot notation is Objective-C syntactic sugar that calls the Objective-C setter and getter methods. The -> arrow notation is C syntax that will dereference the object's pointer and access the struct field for the object's ivar.
It is important to understand that the dot syntax is actually generating calls to these methods, so you don't try and override those methods and inadvertently include calls to themselves.
The default implementation of a generated method like - (UITextFeild *)myInputField looks something like this
- (UITextFeild *)myInputField {
return self->_myInputField;
}
But Objective-C has yet another syntactic helper allowing you to access _myInputField without writing out self->. So the following implementation is identical.
- (UITextFeild *)myInputField {
return _myInputField;
}
There are some good reasons for using direct ivar access -- the biggest reasons being implementation of custom setters and getters, performance, and careful control over KVO language features. But in modern Objective-C it should be avoided unless you really know what you're doing.
If you want to learn more, read Apple's documentation on Objective-C

self.myInputField.text = #"another test";
That code calls the myInputField getter method. There can be good reason for doing this, so it is usually safest.
self->_myInputField.text = #"text field test";
That code directly accesses the _myInputField instance variable.
The myInputField getter method in this case also accesses the _myInputField instance variable, which is why the two calls seem to do the same thing. But that is just an implementation detail; it is perfectly possible for a getter method to access a differently named instance variable, to perform other actions (side effects), or to access no instance variable at all.

Related

'does not have member' when calling objective C setter method from Swift

After importing the objective C robbiehanson/XMPPFramework into a swift project (setting up build setting, bridging header, etc). I am able to call normal methods in the imported classes and set properties directly.
However, certain instance methods that set properties cause immediate errors as if they don't exist in the instances I'm calling them on. For example:
- (void)setMyJID:(XMPPJID *)newMyJID
{
[self setMyJID_setByClient:newMyJID];
}
Or even the setMyJID_setByClient:newMyJID method which actually does the setting.
In two separate objective c example projects I have looked at, the setMyJID method is being called from other classes. However, while I am able to call other instance methods on the class, I can't call this one. Since I am not very familiar with objective c, I though this might be because it wasn't declared in the header file, causing some swift specific problem, but attempts to add a declaration for it did not help.
I am able to set the relevant property directly, but this is not only undesirable, I also would like to understand why I am not able to call certain methods.
I am attempting to make the call on an instance of the XMPPStream class like this
//This shows immediate error: XMPPStream does not have a member named 'setMyJID'
stream.setMyJID(XMPPJID.jidWithString(someXMPPAddress)
// This works perfectly
stream.myJID = (XMPPJID.jidWithString(someXMPPAddress))
Any help would be appreciated.
In the XMPPStream class, myJID is declared as follows:
#property (readwrite, copy) XMPPJID *myJID;
In Objective-C, this means that there are actually two methods on the XMPPStream class that conform to the following signatures:
- (XMPPJID *)myJID;
- (void)setMyJID:(XMPPJID *)myJID;
So, from Objective-C code, you can call them like any other method. However, as you know, you also have the option of using the syntactic sugar in the language known as "dot notation":
// getter with dot notation
XMPPJID *jid = stream.myJID;
// setter with dot notation
stream.myJID = jid;
However, in Objective-C, these dot notation expressions are directly translated into calls to the getter and setter. They're just there to look nice.
Things are different in Swift. When you have a property, like this one:
var myJID: XMPPJID
this does not mean that there exist separate getter and setter methods, like you might be imagining:
func myJID() -> XMPPJID {}
func setMyJID(jid: XMPPJID) {}
In Swift, you must access properties using dot syntax.
Knowing this, your problem becomes obvious. When you tried:
stream.setMyJID(XMPPJID.jidWithString(someXMPPAddress)
Swift tried to run the instance method setMyJID of stream, and found, rightly, that it did not exist! This, of course:
stream.myJID = (XMPPJID.jidWithString(someXMPPAddress))
works perfectly, because you're setting a property as Swift requires.
As an educational aside, you may sometimes see cases where, when accessing Objective-C properties from Swift, you not only can, but must use the getter and setter methods - dot notation won't even work! This seems totally counterintuitive, but there's a good reason for why this happens. One example of this that I can think of off the top of my head is the verbosely-named UIView property translatesAutoresizingMaskIntoConstraints, used for view layout. If you try to use it in Swift, like so:
// Set translatesAutoresizingMaskIntoConstraints to false on self
translatesAutoresizingMaskIntoConstraints = false
you would get a compilation error! Specifically,
Cannot assign to 'translatesAutoresizingMaskIntoConstraints' in 'self'
Why? The answer lies in the UIView headers:
- (BOOL)translatesAutoresizingMaskIntoConstraints NS_AVAILABLE_IOS(6_0); // Default YES
- (void)setTranslatesAutoresizingMaskIntoConstraints:(BOOL)flag NS_AVAILABLE_IOS(6_0);
It turns out that this "property," like many others in the Cocoa frameworks, is actually just a pair of methods that look like property accessors. Because of how Objective-C translates dot notation into method calls, you'd never notice before. Now, though, Swift is stricter – to get and set this "property," you must call the appropriate methods.

Objective-C message syntax

while learning Objective-C I stumbled across the following code, which I do not understand:
RootViewController *rootViewController = (RootViewController *)[self.navigationController topViewController];
As far as I understand
[self.navigationController topViewController]
is sending the message (calling the method) topViewController to self.navigationController.
Looking in the .h File I only find topViewControllerbeing a property, not a function:
#property(nonatomic,readonly,retain) UIViewController *topViewController; // The top view controller on the stack.
Can somebody explain what is happening there?
Thanks in advance!
Either syntax is fine:
[self.navigationController topViewController]
and:
self.navigationController.topViewController
The latter is calling the property's getter method, which probably looks like this:
- (UIViewController *)topViewController
{
return _topViewController;
}
I would prefer the latter if it's been defined as a #property.
The "dot syntax" is another way of calling a method (only methods that do not have any arguments may be called this way).
So the statement:
[self.navigationController topViewController]
is actually interpreted as:
[[self navigationController] topViewController]
which means:
The message navigationController is sent to the object self.
The message topViewController is sent to the object that was returned by navigationController.
A property itself is just a fancy way of defining methods. A readonly property only provides a getter (foo), a read/write property also provides a setter (setFoo:). By default, the compiler generates these methods to access an also implicitly defined variable _foo.
A property is really a convention that means you have ivars with accessor methods, setters and getters, that meet a standard style and provides additional functionality that is derived from the conventional style.
With Objective-C 2.0 we got synthesized properties. That is the compiler will generate a lot of boilerplate code to make ivars and associated setter and getter methods for you that adhere to conventions and provide most importantly consistent memory management and KVC and KVO. (Google those separately).
It also brought the dot syntax, which is syntactic sugar, in other words the compiler interprets it the same way as corresponding bracket syntax.
Both dot and bracket syntax are transformed the same way by the compiler into the same kinds of calls.
There is no functional difference.

objective C underscore property vs self

I'm was playing around with the standard sample split view that gets created when you select a split view application in Xcode, and after adding a few fields i needed to add a few fields to display them in the detail view.
and something interesting happend
in the original sample, the master view sets a "detailItem" property in the detail view and the detail view displays it.
- (void)setDetailItem:(id) newDetailItem
{
if (_detailItem != newDetailItem) {
_detailItem = newDetailItem;
// Update the view.
[self configureView];
}
i understand what that does and all, so while i was playing around with it. i thought it would be the same if instead of _detailItem i used self.detailItem, since it's a property of the class.
however, when i used
self.detailItem != newDetailItem
i actually got stuck in a loop where this method is constantly called and i cant do anything else in the simulator.
my question is, whats the actual difference between the underscore variables(ivar?) and the properties?
i read some posts here it seems to be just some objective C convention, but it actually made some difference.
_property means you are directly accessing the property.
self.property means you are using accessors.
In your case, in the setter method you are calling it, creating a recursive call.
In the course of your experiment, you've set up an endless loop which is why the simulator goes non-responsive.
Calling self.detailItem within the scope of setDetailItem: calls setDetailItem: recursively since your class implements a custom setter method for the property detailItem.
I would refer you to the Apple documentation on declared properties for the scoop on properties, ivars, etc; but briefly, declared properties are a simplified way of providing accessor methods for your class. Rather than having to write your own accessor methods (as we had to do before Objective-C 2.0) they are now generated for you through the property syntax.
The properties are basically a way of the compiler to generate a setter and getter for a given instance variable.
So when you use something like:
id detailItem = self.detailItem;
what you are doing under the hood is:
id detailItem = [self detailItem];
Same for:
self.detailItem = otherDetailItem;
would be:
[self setDetailItem:otherDetailItem];
So when you write the setter yourself.. you get in an infinite loop since you access the method itself in itself.
You can freely make use of the 'self.' notation in your class, just not when you're overriding the setter or accessor because of the mechanism I described above.
Cases in a class where I use the . notation over simply accessing the ivar is when I change the value, you never know inside your class what needs to happen when you change the value. do you have something in terms of a status that should notify some delegate that a status changed? Usually this is not the case, however, just by using the . notation you are making sure that in the future you won't have to refactor some code if you did decide to do some magic in your setter method.
I'll make an example (without ARC enabled):
#property (nonatomic, retain) NSNumber* number;
If you don't synthesize it, you can access it this way:
self.number= [NSNumber numberWithBool: YES];
This case the number is retained.If instead you synthesize it and don't use the property:
#synthesize number;
Later in the file:
number=[NSNUmber numberWithBool: YES];
You haven't used the property, so the number is not retained.That makes a relevant difference between using accessors and synthesized properties.

Passing a value from one object into another with Objective-C

I have a class called GameScene, with is a subclass of a cocos2d Scene.
In there I have two layers. GameLayer and ControlsLayer. You can probably tell already that I want the ControlsLayer to move stuff around in the GameLayer. To be precise, I'm trying to control a cPBody in the GameLayer from the ControlsLayer.
At the moment, I'm trying to route the instructions from the ControlsLayer, back up into the GameScene and then back down into the GameLayer. If that makes sense. Anyway, I can't get it to work. I have a PHP background so I think I'm incorrectly applying my PHP experience to Obj-C.
My thinking is, I should be able to access a property inside a class/object using something like
aThing *someThing = someInstance->aThing;
From the sample code I've been looking at, it looks like this should work. But it doesn't. Here's the code, stripped down to as much as possible http://pastebin.com/d49c9d0be
Rather than knowing how to fix this particular issue, The question is, what don't I understand?
In Objective-C you need to define accessor methods to get at the instance variable, you can't directly access it like that unless you're calling it from the same class type (for instance when you're implementing the NSCopying protocol and need to set private variables, but don't worry about that now).
The easiest way to do that is to define a property in your header using #property(retain) SomeClass *name;, and have Objective-C generate it by putting #synthesize name = instanceVariable; in your implementation. You can then access the variable outside of that class using object.name; or [object name];. For more information take a look in the documentation for properties and Object Oriented programming.
You're not exposing the gameLayer.myBody property in any shape. You'd have to use the #property declaration (assuming objective-c 2.0) (here's an example).
I don't have any PHP background, so I don't know how it may be different in PHP.
The correct way to access a property in an object is as follows:
aThing * someThing = someInstance.aThing; // new style
or
aThing * someThing = [someInstance aThing]; // old style
If you were coding in c, the -> operator would make sense. In objective-c, however, objects are always passed around through pointers. No objective-c variable ever actually holds an object, they just hold pointers to objects. The language designers simply decided to use the [] or . syntax to access members, so that's what we have to do!

How do you name your instance/param values?

Being new to Objective-C (but a long term C/++) programmer I'm looking for advice/recommendations on naming conventions for variables.
My personal preference would be to utilize a prefix for instance variables both for clarity within functions and to prevent shadowing of function parameters. However I'm a fan of properties which rules out prefixes (unless you also prefix your property names, which doesn't work too well and looks daft). Similarly I could use the "self.variable" convention, but only if I make EVERYTHING a property.
So given the code below what's your preferred naming style for instance/function variables? And if you don't bother, how do you deal with shadowing on function params?
#interface GridItem : NSObject
{
CGRect _rect;
...
}
#end
-(void) initFromRect:(CGRect)rect
{
_rect = rect;
...
}
Cheers!
Most Cocoa projects use underbar as a non-IBOutlet instance variable prefix, and use no prefix for IBOutlet instance variables.
The reason I don't use underbars for IBOutlet instance variables is that when a nib file is loaded, if you have a setter method for a connected outlet, that setter will be called. However this mechanism does not use Key-Value Coding, so an IBOutlet whose name is prefixed with an underbar (e.g. _myField) will not be set unless the setter is named exactly like the outlet (e.g. set_myField:), which is non-standard and gross.
Also, be aware that using properties like self.myProp is not the same as accessing instance variables. You are sending a message when you use a property, just like if you used bracket notation like [self myProp]. All properties do is give you a concise syntax for specifying both the getter and setter in a single line, and allow you to synthesize their implementation; they do not actually short-circuit the message dispatch mechanism. If you want to access an instance variable directly but prefix it with self you need to treat self as a pointer, like self->myProp which really is a C-style field access.
Finally, never use Hungarian notation when writing Cocoa code, and shy away from other prefixes like "f" and "m_" — that will mark the code as having been written by someone who doesn't "get it" and will cause it to be viewed by suspicion by other Cocoa developers.
In general, follow the advice in the Coding Guidelines for Cocoa document at the Apple Developer Connection, and other developers will be able to pick up and understand your code, and your code will work well with all of the Cocoa features that use runtime introspection.
Here's what a window controller class might look like, using my conventions:
// EmployeeWindowController.h
#import <AppKit/NSWindowController.h>
#interface EmployeeWindowController : NSWindowController {
#private
// model object this window is presenting
Employee *_employee;
// outlets connected to views in the window
IBOutlet NSTextField *nameField;
IBOutlet NSTextField *titleField;
}
- (id)initWithEmployee:(Employee *)employee;
#property(readwrite, retain) Employee *employee;
#end
// EmployeeWindowController.m
#import "EmployeeWindowController.h"
#implementation EmployeeWindowController
#synthesize employee = _employee;
- (id)initWithEmployee:(Employee *)employee {
if (self = [super initWithWindowNibName:#"Employee"]) {
_employee = [employee retain];
}
return self;
}
- (void)dealloc {
[_employee release];
[super dealloc];
}
- (void)windowDidLoad {
// populates the window's controls, not necessary if using bindings
[nameField setStringValue:self.employee.name];
[titleField setStringValue:self.employee.title];
}
#end
You'll see that I'm using the instance variable that references an Employee directly in my -init and -dealloc method, while I'm using the property in other methods. That's generally a good pattern with properties: Only ever touch the underlying instance variable for a property in initializers, in -dealloc, and in the getter and setter for the property.
I follow Chris Hanson's advice in regards to the underscore ivar prefix, though I admit I do use underscore's for IBOutlets as well. However, I've recently starting moving my IBOutlet declarations to the #property line, as per #mmalc's suggestion. The benefit is that all my ivars now have an underscore and standard KVC setters are called (i.e. setNameField:). Also, the outlet names don't have underscores in Interface Builder.
#interface EmployeeWindowController : NSWindowController {
#private
// model object this window is presenting
Employee *_employee;
// outlets connected to views in the window
NSTextField *_nameField;
NSTextField *_titleField;
}
- (id)initWithEmployee:(Employee *)employee;
#property(readwrite, retain) Employee *employee;
#property(nonatomic, retain) IBOutlet NSTextField *nameField;
#property(nonatomic, retain) IBOutlet NSTextField *titleField;
#end
You can use the underbar prefix on your ivars and still use the non-underbar name for your properties. For synthesized accessors, just do this:
#synthesize foo = _foo;
This tells the compiler to synthesize the foo property using the_foo ivar.
If you write your own accessors, then you just use the underbar ivar in your implementation and keep the non-underbar method name.
Personally, I follow the Cocoa naming conventions, using camel-casing for functions and variables, and capitalized camel-casing for object names (without the leading NS of course).
I find type prefixing makes code more opaque to anyone who didn't write it (since everyone invariably uses different prefixes), and in a modern IDE it's not really that difficult to figure out something's type.
With the introduction of properties I see no need for prefixing "_" to class instance variables. You can set a simple rule (described in your header file) that any variables to be accessed external to the class must be accessed via the property, or by using custom methods on the class to affect values. This to me seems much cleaner than having names with "_" stuck on the front of them. It also properly encapsulates the values so that you can control how they are changed.
I don't like using underscores as prefixes for any identifiers, because C and C++ both reserve certain underscore prefixes for use by the implementation.
I think using "self.variable" is ugly.
In general, I use unadorned identifiers (that is, no prefixes nor suffixes) for instance variables. If your class is so complicated that you can't remember the instance variables, you're in trouble. So for your example, I'd use "rect" as the name of the instance variable and "newRect" or "aRect" as the parameter name.
Andrew: There actually are plenty of Cocoa developers who don't use instance variable prefixes at all. It's also extremely common in the Smalltalk world (in fact, I'd say it's nearly unheard-of in Smalltalk to use prefixes on instance variables).
Prefixes on instance variables have always struck me as a C++-ism that was brought over to Java and then to C#. Since the Objective-C world was largely parallel to the C++ world, where as the Java and C# worlds are successors to it, that would explain the "cultural" difference you might see on this between the different sets of developers.
My style is hybrid and really a holdover from PowerPlant days:
THe most useful prefixes I use are "in" and "out" for function/method parameters. This helps you know what the parameters are for at a glance and really helps prevent conflicts between method parameters and instance variables (how many times have you seen the parameter "table" conflict with an instance variable of the same name). E.g.:
- (void)doSomethingWith:(id)inSomeObject error:(NSError **)outError;
Then I use the bare name for instance variables and property names:
Then I use "the" as a prefix for local variables: theTable, theURL, etc. Again this helps differentiate between local and and instance variables.
Then following PowerPlant styling I use a handful of other prefixes: k for constants, E for enums, g for globals, and s for statics.
I've been using this style for something like 12 years now.
While I love using the underscore prefix for ivars, I loathe writing #synthesize lines because of all the duplication (it's not very DRY). I created a macro to help do this and reduce code duplication. Thus, instead of:
#synthesize employee = _employee;
I write this:
ddsynthesize(employee);
It's a simple macro using token pasting to add an underscore to the right hand side:
#define ddsynthesize(_X_) #synthesize _X_ = _##_X_
The only downside is that it will confuse Xcode's refactoring tool, and it won't get renamed, if you rename the property by refactoring.
Along with what's been said here, be sure to read the Cocoa documentation on Key Value Observing compliant naming. Strictly following this pattern will help you greatly in the long run.