I'm using the following lines to declare a property in my objective-c program.
#property (retain) int Money;
and the syntesize in my implementation file.
Now i wanted to make an addMoney method in my implementation to add an amount of money in my program. I was typing addMoney when i realized that Xcode was saying there is always a method with this name that i could override. It has the following signature.
-(void)addMoney:(NSSet *)objects;
and
-(void)addMoneyObject:(object-type *)object
where do they come from and who is calling them? AND how could i use it by myself? What must i attend to when using this?
This method does not actually exist. Xcode is helping you out by completing some common naming patterns. It's somewhat common to have a situation like this:
#class Thing;
#property (nonatomic, retain) NSMutableSet *things;
- (void)addThings:(NSSet *)someThings;
- (void)addThing:(Thing *)aThing;
Xcode is just trying to make it a little easier to type that. But the methods don't really exist unless you create them.
Side note: you can't retain an int, so I assume this isn't real code. That's fine. Do make sure your properties start with a leading lowercase (money). It's not just individual style. ObjC relies on Key-Value Coding for many things. That requires that things be named in a certain way or it won't work.
Is Money a ManagedObject (Core Data object)? If so, that method may be being created for you. Synthesized properties should provide setter and getter but that method would look like -(void)setMoney:(int)money and -(int)Money
Related
Say this is in my header file:
#interface AppDelegate : NSObject <NSApplicationDelegate>
#property (weak) IBOutlet NSSlider *slider;
- (void)doSomething;
#end
…and this is the *m:
#implementation AppDelegate
- (void) doSomething {[self.slider setFloatValue:0];}
#end
I'm new to Xcode and Objective C, and I would like to use and understand the modern “tools” presented by Apple in its documentation, namely ARC, or here more specifically the ability to skip #synthesize.
If I understood correctly, #property (weak) IBOutlet NSSlider *slider; does a few things for me, including:
creating an instance variable called _slider;
creating a getter named slider;
creating a setter named setSlider.
I've been doing C++ until now, so I see instance variables as the equivalent of what I am calling (rightly, I hope) members of my C++ classes, which I incidentally always call _member.
I understand that the whole point of encapsulation is that, if you're outside a given class, you have to use accessors to access those variables; they are private to you, so there's no way you can access them via _member even if you tried.
But, when I'm writing my *.m file of my class, _member means something. Back to my example, I think self.slider and _slider are equivalent. The latter comes naturally to mind first, as it saves a few character.
My question is: are the two absolutely equivalent?
I know this looks similar to this question, for example, but here’s a few reasons why I wanted to ask myself:
I don’t use #synthesize, so I’m really not the one creating _slider, and I wonder if this makes a difference (I believe this is a fairly recent improvement of ObjC, and most answers still refer to #synthesize);
it seems that on average, most conversations end up with “so, just use self.name”, but I don’t grasp if this is just a recommendation, a convention, of something more important (with an impact on, say, the performance);
similarly, some say you should only use _name in methods like dealloc and its friends; but I don’t write those thanks to ARC, so does this mean I should never use _name? If so, why?
I hope this justifies this post, I apologies if I missed a preexisting answer. Thanks in advance for your help.
self.name = compiles to [self setName:] this is very different then setting the variable directly.
One of the main reasons that using the default setter differs deals with key value observing often referred to as KVO. Using the setter will notify observers of changes, setting the _name directly will not.
Thats not to say you can't fire the events your self with willChangeValueForKey: and didChangeValueForKey:, but the default implementation will handle that for you. So as you say outside the class accessing them you have to use the property get/set but inside your class setting the variable directly will lose out on some notifications. I'm sure there are other differences this is the first that comes to mind.
Using the variable directly does have it's use cases, such as a custom property setter. I think the main take away is the dot syntax is a hidden function call to get/set.
https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/KeyValueObserving/Articles/KVOCompliance.html
Under basic circumstances, where you use the pre-made accessors, you could probably get away with using _slider or self.slider within your class interchangeably. They're not equivalent in how they compile necessarily, but the functionality could be said to be equivalent.
The bigger issue comes into play when you start overriding those accessors. When those accessors do more than just "getting" or "setting" a variable, such as accessing some sort dependency variable, accessing the instance variable directly bypasses that functionality that the accessors provide. In these cases, I don't think it can be said that the two are equivalent at all.
With the current version of Objective-C, what are the official standards and best practices for declaring ivars, using #property and #synthesize? There are a lot of posts and resources on the topic but most of them are fairly antiquated from a year or two ago. I recently learned to only declare ivars in a statement block in the implementation of a class so that the encapsulation principles of OOP aren't broken but is declaring ivars even necessary in this day and age? What would be a possible use case where doing:
#interface MyClass()
#property (nonatomic) NSString* data;
#end
#implementation MyClass{
#private
NSString* _data;
}
#end
is necessary? To further that, is it ever necessary to use #synthesize? My understanding is that using #property will auto-synthesize both the accessor methods as well as the backing ivars. I've done some experimentation and I noticed that when I don't declare NSString* _data', I can still access_data' in my class implementation. Does that mean that declaring ivars come down to a matter of style, up to the discretion of the programmer? Could I condense my code and remove all ivar declarations in the statement blocks in my implementation and just use #property in my private interface? If that's not the case, what are the advantages and disadvantages of explicitly declaring ivars?
Finally, #dynamic. From what I can gather, it's used to say to the compiler, "Hey compiler, don't auto-generate the accessor method and don't worry if you don't find an implementation for it, I'll provide one at runtime". Is that all #dynamic is used for or is there more to it?
I just want to clarify all these things because it seems like there's a lot of different opinions and that there's not necessarily one right answer. Plus as Objective-C grows and progresses, those answers will change so it'll be nice to have a concise and up-to-date guide. Thanks everyone!
(Also if there's anything that I could word better or make clearer, let me know)
EDIT:
In summary, what I'm asking is this:
1) Is declaring ivars with modern Objective-C necessary?
2) Can I achieve the same effects of declaring ivars and corresponding properties by just using #property?
3) What is #dynamic used for?
4) Can I completely forgo the use of #synthesize or is there a good use case for it?
Upvote and down vote as you see fit.
There's a lot to answer here. I'll break it down:
Declaring ivars
As you've correctly noted, modern versions of the compiler will synthesize backing instance variables for declared #properties. The exception to this is on 32-bit Macs, where the modern Objective-C runtime, including non-fragile instance variables, is not available. Assuming your application is not targeting 32-bit OS X, you don't need to explicitly declare the backing ivar for an #property.
If you still want to use an ivar directly, without a corresponding #property (something I consider a bad idea most of the time), you of course must still explicitly declare the ivar.
#dynamic
#dynamic is as you've said meant to tell the compiler "don't synthesize accessors for this property, I'll do it myself at runtime". It's not used all that often. One place it is used is in NSManagedObject subclasses, where if you declare a modeled property in the header, you don't want to compiler to complain that there's no implementation of accessors for that property, nor do you want it to generate accessors itself. NSManagedObject generates accessors for modeled properties at runtime. The story is similar for custom CALayer subclasses.
#synthesize
#synthesize explicitly tells the compiler to synthesize accessor methods, and (on iOS and 64-bit Mac) a corresponding ivar for the specified property. There are three main cases where you still need to use it:
32-bit Mac apps.
If you've written your own custom setter and getter (or just getter for readonly properties). In this case, the compiler won't synthesize accessors because it sees yours. However, it also won't synthesize the backing ivar. So, you must use #synthesize someProperty = _someProperty;, to tell the compiler to synthesize an ivar. It still won't synthesize accessor methods of course. Alternatively, you can explicitly declare a backing ivar. I favor using #synthesize in this case.
If you want to use a different name for the property's backing ivar than the default (property name with an added underscore prefix). This is rare. The main case I can think of for using it is when transitioning existing, older code, that includes direct ivar access and where the ivars are not underscore-prefixed.
Best current practice seems to be to use properties for all ivars placing the property either in the .h file if they are to be exposed and in the .m file in a class extension if local to the class.
No #synthesize is needed unless the ivar needs to be different than the underscore prepended property name.
Yes, #dynamic is as you describe.
Further, it is no longer necessary to declare local instance methods or order such that the method is above the use.
First off, #synthesize is gone for these scenarios: do not have to do it any more.
Secondly, you don't need the private ivar anymore either.
So in essence, you can just do properties.
The way of controlling access is the same idiom that had become popular before MOC dropped: put the property in the public interface as readonly and then make a readwrite version in the private interface (which should be, as you show above, merely the name with open and close parens).
Note also, that many of the things that cluttered up the public interface in the past can now ONLY be in the private interface, so for instance IBOutlets, etc., since the controller is going to be the only thing diddling them.
I never see #dynamic used anywhere except in CoreDate-generated entities.
For someone who first worked with C++ where the dream was always that the header/interface merely show the user of the class what they needed and all other details would be hidden, I think MOC (Modern Objective C) is a dream come true.
BTW, highly recommend the intro session from WWDC Modern Objective C (from 2012) and the one this year was great too.
I'm having a hard time understanding why I need to declare Instance Variables. Let me explain what I mean..
for example..
#interface LearningViewController : UIViewController {
UILabel *myText; // <--- Instance Variables
}
#property (nonatomic,retain) IBOutlet UILabel *myText;
-(IBAction)method:(id)sender;
#end
this can also be done as
#interface LearningViewController : UIViewController {
//instance variables go here, but are not declared, I just leave this field blank
}
#property (nonatomic,retain) IBOutlet UILabel *myText;
-(IBAction)method:(id)sender;
#end
as you can see.. in the latter example I ONLY built the setter / getter for the UILabel *myText
but in the former I declared the Instance Variables too.
Both end up working in the end
#implementation LearningViewController
#synthesize myText;
-(IBAction)method:(id)sender {
[myText setText:#"hey"];
//or
NSString *myObject = [[NSString alloc]initWithString:#"hey"];
[myText setText:myObject];
}
now both things produce the same result. So my question is, why? and what are the benefits of doing them either way?
And why would I build and object
NSString *myObject = [[NSString alloc]initWithString:#"hey"];
myText.text = myObject;
when I can just do
[myText setText:#"hey"];
thanks in advance.
Also, there are times when you want to use a protected or private iVar within a class and not make a property out of it. (for example, when you don't want to allow access of an iVar to anything but an instance of this class (private) or its descendants (protected). Properties declared in the header are available to any object that can "see" the target object. Automatically declaring ivars in the header as properties (with or without the declaration inside the curly braces) might be bad from the standpoint of information hiding.
You can also add an implementation section to your .m file: any properties you declare there will be private to the class. The benefit (obviously) is both in achieving information hiding where needed, and the ability to use the dot notation.
Originally Objective-C did not have properties and # synthesize did not exist. You had to declare your iVar (instance Variable) and write your own setters and getters.
When the language and runtime were revised to include properties and #synthesize, things were nicer. You no longer had to write your setters and getters. However you still had to declare your iVar.
Later still, the language and runtime evolved more and today, you don't even have to declare your iVar. (Although I tend to write #synthesize example = _example; so I can control what the generated iVar is named.)
This is a new feature and is only supported by relatively recent versions of the runtime. iOS versions less that 4.x are not supported, as are older versions of OSX.
If you are building software for today and the future, Go ahead and leave them out, If yot need legacy support, leave them in.
On the second part of the question, you are simply using the dot notation. You can set your myText.text equal to #"hey", the same way you are doing it in the second example.
[myText setText:#"hey"];
is synonymous to
myText.text = #"hey";
You don't need to declare an NSString to hold your value ahead of time.
You can leave iVars out, however I do not agree leaving out the iVars. The .h file in OOP is typically a header file that displays all variables and methods. It declares them. Assuming in the future you want to see what this class does, you just refer to the .h file. Or assuming someone else needs to look at that class, or use that class with his code to communicate with it. It makes it easier to look at the variables, see what is declared and what is not. That is, if you want to be programming professionally.
Now it really depends on what you want to do. The reason you would create an object is that so you are able to release it at a later time. So you continue to use it, and when you are done you just finish using it. Now creating instance variables for the whole class when they are just used in one method is not a good design decision. It is poor in a sense that the whole class is storing the variable, when in fact it is only used in one method. In this case, you should only create that object in that very method, and release it as soon as you're done with it.
Now sometimes doing
[myText setText#"hello"];
works. It really depends on your code. I guess the only way to really know the difference in situations is practice. Sometimes you need to set the label into another object, thus creating an object. Otherwise, it gets autoreleased etc...
Anyway, basically, use instance variables only for variables that are going to be used globally. And UI elements of course (since they are used by the whole class and interface builder).
Hope this helps.
As your code demonstrates, you don't technically need to declare instance variables, most of the time.
One critical exception to this is when you are compiling for the old (< 4.0) iOS runtime, as well as possibly the 32-bit Mac OS X runtime using GCC, which does not support the synthesis of instance variables.
Additionally, if you want to reserve space for later addition of instance variables (can be relevant if you are producing a framework and expect to extend a class at a later point), you'll need to explicitly declare the instance variables.
Edit: Long story short: Legacy, portability and extensibility concerns proscribe explicit ivars. For applications targeting 10.6, and especially 10.7, there is little or no need to declare them.
First I have to do
#property (retain) aMember;
Then in implementation file I got to do
#synthesize aMember;
Then in dealloc, I got to do
self.aMember= nil; (or [aMember release])
That's 3 times writing what essentially is the same
Is there a way to speed this up?
I mean I can drag drop a control from a IB and xcode automatically generate those codes why I can't do that for more normal codes?
As someone coming from C# and managed languages for my day job I completely agree with you in questioning this 3 step process. In fact its almost crazy easy to create properties in C# in MS Visual Studio, but I digress.
Even though there are these 3 lines you have to write there is a huge amount of work going on under the covers for your.
Your declaration of the #property tells objective-c some important attributes (atomic, nonatomic, retain, copy, etc) in how to deal with your property when it is set by users of your class. When you think about this, these attributes (without you writing any code) are; helping you create thread safe code, handling references to objects so you don't have to worry about them disappearing on you, or copying values so you have your own copy of an object. The #property is also important since it is declared in your header file (typically). This give other developers an idea of the properties of your class and some small hints as to how objects they pass into those properties will be handled during its lifetime.
The #synthesize is also doing quite a bit of work by creating the getters and setters for that property, that also handle all sorts of memory management for you. You don't need to worry about releasing the old references and correctly referencing the new object. This alone to me is a great feature, especially when you are new to objective-c and it is easy to forget to deal with memory management at every turn. The #synthesize just does it for you and you don't have to write all the get and set code yourself.
The dealloc call is just life in a non-memory managed environment. While it adds additional steps, I appreciate the benefits that explicit memory management allows in a constrained environment such as the phone.
So all 3 steps are required, are different and when you think about it actually do quite a bit of work for you under the covers.
Unfortunately, that's how it is (for now). Apple had recently toyed with allowing Clang to implicitly synthesize your properties, which would have reduced your work to:
#interface Blah : NSObject
#property (retain) Blorg *blorg;
#end
#implementation Blah
- (void)dealloc {
[blorg release];
[super dealloc];
}
#end
When you didn't want an instance variable to be synthesized, you'd just explicitly put #dynamic blorg in your implementation. But this feature was removed due to some unforeseen complications, despite mostly positive reactions from developers.
So, I think it's safe to expect that Apple's still working on this. But for now, you do need to explicitly synthesize.
A few other notes:
If you are using garbage collection, you don't need to implement -dealloc: just make sure to do any last-minute cleanup in -finalize (such as notification unregistration).
You could also avoid the -dealloc bit by wrapping your instance variable in a C++ class which performs memory management during construction and destruction: #property prop_wrapper<Blorg> blorg; would work. Then, when your object is destroyed, ~prop_wrapper() would be called on your object. I've done this, and it works, but I recommend against it, since it doesn't play nice with KVO and KVC.
You could iterate through the properties of an object, and release those that are annotated with copy or retain. Then, in -dealloc, you'd have something like [self releaseProperties]. I've also done this, but I also recommend against it, since it can cause subtle problems which may result in inexplicable crashes if you're not careful.
To actually add a member variable in objective-c you don't need to do any of that.
What you're doing in those 3 steps is:
Declare properties for a member variable. (In your case you are indicating that you want the property setter to 'retain' the object that it sets your member variable to)
Declare the property getters and setters in a default way for your property.
Release the object that your property is retaining.
IF you only wanted to declare a member variable, all you had to do was declare it inside your class:
#interface SomeClassObject : NSObject {
int someMemberVariable;
}
#end
That's 3 times writing what essentially is the same
No it isn't.
#property (retain) aMember;
The above line declares a property so that the compiler knows it is OK to send the messages -aMember and -setAMember: to objects of your class. It also tells the compiler (and developers) that the property is a retain property (i.e. the object you set the property to will be retained), that it is read/write and that it is atomic.
#synthesize aMember;
The above line tells the compiler that it should automatically generate the setter and getter methods for the declared property. You can leave that out but then you have to write your own setter and getter.
[aMember release]; // in dealloc
Is there to tell the runtime that when the object is being deallocated, it no longer needs to hold a reference to that instance variable. This is necessary because, when you use reference counting rather than garbage collection, the runtime does not automatically clean up unwanted objects.
Each of those lines does a different thing. So you are not doing the same thing three times.
In the Modern Objective-C runtime, you can do something like this:
#interface MyClass : NSObject {
}
#property NSString *stringProperty;
#end
#implementation MyClass
#synthesize stringProperty;
#end
It is my understanding with the modern runtime this will not only synthesize the accessors for my property, but also the instance variable itself, so I could then say in one of this class's methods [stringProperty length]; and it would work just as if I'd declared an instance variable.
I've started using this in all my code now, because, well it's one less thing I have to write over and over again. And I've heard with the clang 2.0 compiler, I'll even be able to skip the #synthesize (but that's another matter). But I've been wondering, what are some of the downsides to doing this? When might I truly need an instance variable in addition to my properties?
I know there are sometimes when I want to keep a variable private and not give access to it externally (but then I usually just declare the property in my private class extension, or I don't create a property for it at all, if I don't need accessors for it).
Are there any times when I wouldn't want to do this?
One possible reason why it might be advisable to not use synthesized instance variables is they are a bit more of a pain to debug in the current version of Xcode (3.2.5). They don't seem to show up in the live debugger view when running code through GDB, the only way to get at them is through the gdb console like po [0xOBJ_ADDRESS propertyName]. Not exactly as nice as a standard, non-synthesized ivar.
Maybe Xcode 4 fixes this but I don't have enough experience with it to say (and it's still under NDA).
More info on this SO question: Seeing the value of a synthesized property in the Xcode debugger when there is no backing variable
You may want to provide many properties for a single instance variable, e.g., :
for accessing an angle value both in degrees and radians
for accessing coordinates both in rectangular and in polar systems
In these cases, you don't want to synthesize instance variables (it already exist) nor accessor methods (you want to provide them for doing conversions).
Anytime you need to make a conversion (unless someone knows a better way) in a class you need to serialize. For example if you have a class that has a numeric value. You cannot serialize an integer so you store it as a NSNumber in the class but the property is a integer type.
Another example is if you code as Apple recommends when working with CoreData. They say you should create a custom class derived from NSManagedObject as the Class for your managed object and use a property for each attribute. Then you would use #dynamic instead of #synthesize and no iVar is needed at all.
But I've been wondering, what are some of the downsides to doing this? When might I truly need an instance variable in addition to my properties?
Possible reasons:
it allows you to change the instance variable in init and dealloc without tripping over subclass overrides or KVO.
the app will compile and run in 32 bit mode on Mac OS X. There are still some Intel Macs out there that don't support 64 bit.
I'm not sure how valid the first point really is. There may be other ways around the issues. The second point is game over though if you need to support older Macs.
One other reason is to avoid shortcuts to direct variable access.
I try to follow the personal coding convention:
- object variable: prefix with underscore '_xxx'
- property: named without underscore 'xxx'
This ensure that I never write unintentionally something like
xxx = value;
or
[xxx someMessage];
I want to always use the getter/setter.
self.xxx = value;
[self.xxx someMessage];
This is particularly useful when you are using lazy init for object variables...