I have seen this code in most of the time. Here there are two variable names defined and in the implementation it synthesizing by assigning. Whats the purpose of doing some thing like this? Like keeping 2 separate variable names. Is this sort of a convention?
Test.h
#interface Test {
id<something> _variable1;
}
#property (nonatomic, retain) id<something> variable2;
Test.m
#synthesize variable2 = _variable1
There is only one variable. The thing named variable2 is actually a property, which is basically a syntactic shortcut for a get/set method pair. When defining a property, you can either write the get/set methods explicitly...
- (void)setVariable2:(id<something>)value {
if (_variable1 != value) {
[_variable1 release];
_variable1 = [value retain];
}
}
- (id<something>)variable2 {
return _variable1;
}
...or use the #synthesize construct to generate the above methods automatically, thus sparing you a lot of monotonous typing. (It also emits code to release _variable1 on destruction of the object, which I haven't included here.)
Sometimes, however, you might want to implement one or other of these methods differently to the default. In this case, you would write your own. You can even mix together #synthesize and a custom version of just one of the methods.
Related
I'd like to define a member in objective C class that can only be read outside the class (public getter). The writing (setter) however shell remain private.
I've read that It's possible to conceal object's setter using the readonly property while exposing the getter using #synthesize syntax but I'm not sure how it works exactly.
Base on this information here's what I did, and I wonder what's happening here under the hood, and if this is the proper way of doing so ?
#interface MyObject : NSObject
//This line suppose to conceal both getter and setter.
#property (readonly) MyCppBaseObject *myCppBaseObject;
- (void)setMyCppBaseObject:(NSString *)SomeInput;
#end
// This line suppose to tell the compiler that the getter is exposed
#synthesize myCppBaseObject = _myCppBaseObject;
#implementation MyObject
-(void)setMyCppBaseObject:(NSString *)SomeInput {
if (someCondition) {
self.myCppBaseObject = new myCppObjectDerive1(...);
} else {
self.myCppBaseObject = new myCppObjectDerive2(...);
}
}
#end
P.S. I've seen a different approach explained in the following link, but I wish to understand the above implementation.
First, you should use the private extension described in the link you provide. That's the correct way to do this.
But to your question, what you've written here is not quite correct.
#property (readonly) MyCppBaseObject *myCppBaseObject;
This line makes a promise to implement -myCppBaseObject. That's all it does. It's just a promise. If you fail to live up to your promise, the compiler will auto-generate (synthesize) one for you using a backing ivar.
- (void)setMyCppBaseObject:(NSString *)SomeInput;
This line is not correct for your purposes. It's making a public setter. But you said you don't want the setter to be public. You could put this in a private extension, however.
#synthesize myCppBaseObject = _myCppBaseObject;
This asks the compiler to create a backing ivar _myCppBaseObject for the property myCppBaseObject. This is the default behavior, however, and so isn't required. (There was a time when it was, but that was a very long time ago.)
-(void)setMyCppBaseObject:(NSString *)SomeInput {
if (someCondition) {
self.myCppBaseObject = new myCppObjectDerive1(...);
} else {
self.myCppBaseObject = new myCppObjectDerive2(...);
}
}
This code is completely incorrect. It is an infinite loop, since self.x =... is syntactic sugar for [self setX:...]. What you mean is:
_myCppBaseObject = ...
You're going to create a lot of headaches having the name of the custom setter be exactly the expected name of the default setter, but with a different type. Don't do this. In theory it could work most of the time, but don't. Especially when there's dot-syntax involved. Especially since one of your objects does not appear to be ARC-compatible (i.e. a C++ object), this is going to really be a trap for really confusing problems. Name your setter differently.
I've seen in a few iPhone examples that attributes have used an underscore _ in front of the variable. Does anyone know what this means? Or how it works?
An interface file I'm using looks like:
#interface MissionCell : UITableViewCell {
Mission *_mission;
UILabel *_missionName;
}
#property (nonatomic, retain) UILabel *missionName;
- (Mission *)mission;
I'm not sure exactly what the above does but when I try to set the mission name like:
aMission.missionName = missionName;
I get the error:
request for member 'missionName' in something not a structure or union
If you use the underscore prefix for your ivars (which is nothing more than a common convention, but a useful one), then you need to do 1 extra thing so the auto-generated accessor (for the property) knows which ivar to use. Specifically, in your implementation file, your synthesize should look like this:
#synthesize missionName = _missionName;
More generically, this is:
#synthesize propertyName = _ivarName;
It's just a convention for readability, it doesn't do anything special to the compiler. You'll see people use it on private instance variables and method names. Apple actually recommends not using the underscore (if you're not being careful you could override something in your superclass), but you shouldn't feel bad about ignoring that advice. :)
The only useful purpose I have seen is to differentiate between local variables and member variables as stated above, but it is not a necessary convention. When paired with a #property, it increases verbosity of synthesize statements – #synthesize missionName = _missionName;, and is ugly everywhere.
Instead of using the underscore, just use descriptive variable names within methods that do not conflict. When they must conflict, the variable name within the method should suffer an underscore, not the member variable that may be used by multiple methods. The only common place this is useful is in a setter or in an init method. In addition, it will make the #synthesize statement more concise.
-(void)setMyString:(NSString*)_myString
{
myString = _myString;
}
Edit:
With the latest compiler feature of auto-synthesis, I now use underscore for the ivar (on the rare occasion that I need to use an ivar to match what auto-synthesis does.
It doesn't really mean anything, it's just a convention some people use to differentiate member variables from local variables.
As for the error, it sounds like aMission has the wrong type. What it its declaration?
This is only for the naming convention of synthesize properties.
When you synthesize variables in the .m file, Xcode will automatically provide you _variable intelligence.
Having an underscore not only makes it possible to resolve your ivars without resorting to using self.member syntax but it makes your code more readable since you know when a variable is an ivar (because of its underscore prefix) or a member argument (no underscore).
Example:
- (void) displayImage: (UIImage *) image {
if (image != nil) {
// Display the passed image...
[_imageView setImage: image];
} else {
// fall back on the default image...
[_imageView setImage: _image];
}
}
This seems to be the "master" item for questions about self.variableName vs. _variablename. What threw me for a loop was that in the .h, I had:
...
#interface myClass : parentClass {
className *variableName; // Note lack of _
}
#property (strong, nonatomic) className *variableName;
...
This leads to self.variableName and _variableName being two distinct variables in the .m. What I needed was:
...
#interface myClass : parentClass {
className *_variableName; // Note presence of _
}
#property (strong, nonatomic) className *variableName;
...
Then, in the class' .m, self.variableName and _variableName are equivalent.
What I'm still not clear on is why many examples still work, even tough this is not done.
Ray
instead of underscore you can use self.variable name or you can synthesise the variable to use the variable or outlet without underscore .
Missing from the other answers is that using _variable prevents you from absentmindedly typing variable and accessing the ivar rather than the (presumedly intended) property.
The compiler will force you to use either self.variable or _variable. Using underscores makes it impossible to type variable, which reduces programmer errors.
- (void)fooMethod {
// ERROR - "Use of undeclared identifier 'foo', did you mean '_foo'?"
foo = #1;
// So instead you must specifically choose to use the property or the ivar:
// Property
self.foo = #1;
// Ivar
_foo = #1;
}
I'm still new to Objective-C and I recently learned how to make properties, so far so good, but one thing that bothers me is that the setter and getter methods are still publicly available even after the property is made.
let's say I have the following code:
// myClass.h
#interface myClass : NSObject {
int _startPos;
}
#property (assign, readwrite, setter = setStartPos:, getter = getStartPos) int startPos;
-(void) setStartPos: (int) pos;
-(int) getStartPos;
#end
the implementation file should be rather self-explanatory, I'm not trying to do anything specific.
Now, I read somewhere, and tried it in practice that if you make a category in the implementation file, and add some methods to that, it's possible to make those methods invisible (aka private) to things outside of the myClass.m file.
"Alright" I think, and decide to try it out:
//myClass.m
#import <Foundation/Foundation.h>
#import "myClass.h"
#interface myClass (hidden)
-(void) setHiddenStartPos: (int) hPos;
-(int) getHiddenStartPos;
#end
#implementation myClass (hidden)
-(void) setHiddenStartPos: (int) hPos {
_startPos = hPos;
}
-(int) getHiddenStartPos {
return _startPos;
}
#end
#implementation myClass
-(void) setStartPos: (int) Pos {
[self setHiddenStartPos: Pos];
}
-(int) getStartPos {
return [self getHiddenStartPos]; //this is to see if I can get the value from the hidden methods through the non-hidden ones
}
#end
that's all fine, and testing it in main() I can see that the methods with "hidden" in their name are in fact inaccessible, and therefore act as if they are private.
Then I tried to add this to the header file:
#property (assign, readwrite, setter = setHiddenStartPos:, getter = getHiddenStartPos) int
to see if I could access the hidden methods through the property
but when I did that, the hidden methods became accessible in main() and the whole plan with making the methods only accessible through the property went down the drain
So I ask you, is there a way to make methods inaccessible to anything BUT the property and/or the object itself?
Edit: I realize that getters don't usually have get in the name, so please stop commenting on it?
also to emphasise what I meant:
I wanted to make properties like in c#, where the content of the setters and getters are private to the property itself
public int exampleProperty
{
set{...}
get{...}
}
it doesn't use methods as getters and setters, and therefore the code in the setters and getters are accessible to only the property, JUST like the code within a method is local to the method itself
Add a class continuation in your .m file. i.e.:
#interface myClass ()
#property (assign, readwrite, setter = setHiddenStartPos:, getter = getHiddenStartPos) int hiddenStartPos;
#end
#implimentation myClass
#synthesize hiddenStartPos = _hiddenStartPos;
...
#end
Have a look at: What is an Objective-C "class continuation"?
PS: Your getters should just be hiddenStartPos rather than getHiddenStartPos...
It seems to me that the your confusion comes from misunderstanding exactly what an #property declaration is. It is essentially a declaration that setter and getter methods exist.
So, this
#property int hiddenStartPos;
is the same as this
- (int)hiddenStartPos;
- (void)setHiddenStartPos;
So, the implementation of these two methods is the implementation of the property. By decaring the property in the .h file, you're advertising to anyone who imports the .h that the class in question implements these two methods (the getter and the setter, respectively).
I also want to reemphasize that getter methods should not be prefixed with "get" in Objective-C.
You're over-thinking what "private" means. In ObjC, "private" just means "not visible." It doesn't mean "not callable." The way you make a method private is to not put it in your .h file, which declares your public interface.
There is no way to control who passes a message. This is a key fact of ObjC and cannot (and should not) be changed. ObjC is a dynamic language. At runtime, I am free to generate selectors and call performSelector: on any object I want. Anything that stopped that would either (a) introduce significant performance penalties, or (b) break many very useful and common techniques in ObjC (probably both). ObjC is not Java or C#. It's not even C or C++. It's Smalltalk on top of C. It's a highly dynamic language and that has a lot of strengths. Unlearning other languages is the first step towards becoming a good Cocoa developer.
It would be nice to have a compiler-checked #private for methods (of which properties are just a special case), and it would especially be awesome to have a compiler-checked #protected for methods (these exist for ivars). These would make it slightly simpler to avoid some kinds of mistakes. But that's the only way you should be thinking about this. The goal is not to protect one part of the code from another part of the code. The other code is not the enemy. It's all written by people who want the program to work. The goal is to avoid mistakes. Correct naming, consistency, and the absolute elimination of warnings is how you achieve that in ObjC.
So yes, I'd love to be able to put #protected in front of my #property declarations occasionally. Today you can't, and there is no real equivalent (I sometimes use a +Protected category in a separate header, but it's generally more trouble than its worth). But that said, having it wouldn't change very much, and I only find a case where I would even use this a few times a year. I can't think of single case where #private for a method would have been really useful, though.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How does an underscore in front of a variable in a cocoa objective-c class work?
In objective C I am seeing lots of code with a underscore before variable names e.g _someVariable
why is that? also how to you write accessors i.e get and set method for such a variable.
The underscores are often used to show that the variables are instance variables. It is not really necessary, as ivars can have the same name as their properties and their accessors.
Example:
#interface MyClass : NSObject {
NSString *_myIVar; // can be omitted, see rest of text
}
// accessors, first one is getter, second one is setter
- (NSString *) myIVar; // can be omitted, see rest of text
- (void) setMyIVar: (NSString *) value; // can be omitted, see rest of text
// other methods
#property (nonatomic, copy) NSString *myIVar;
#end
Now, instead of declaring and coding the accessors myIVar and setMyIVar: yourself, you can let the compiler do that. In newer versions, you don't even have to declare myIVar in the interface. You just declare the property and let the compiler synthesize the rest for you. In the .m file, you do:
#implementation MyClass
#synthesize myIVar; // generates methods myIVar and setMyIVar: for you,
// with proper code.
// also generates the instance variable myIVar
// etc...
#end
Be sure to finalize the string:
- (void) dealloc {
[myIVar release];
[super dealloc];
}
FWIW, if you want to do more than the default implementation of the getter or setter do, you can still code one or both of them yourself, but then you'll have to take care of memory management too. In that case, the compiler will not generate that particular accessor anymore (but if only one is done manually, the other will still be generated).
You access the properties as
myString = self.myIVar;
or, from another class:
theString = otherClass.myIVar;
and
otherClass.myIVar = #"Hello, world!";
In MyClass, if you omit self., you get the bare ivar. This should generally only be used in the initializers and in dealloc.
Don't do it.
Single leading underscores are an Apple internal coding convention. They do it so that their ivar names won't collide with yours. If you want to use a prefix on your ivar names, use anything but a single underscore.
this is a naming convention normally used for c++ to define instance variable which are private
like in a class u may have
private:
int __x;
public:
int GetX()
{
return this.__x;
}
this is a naming convention, i was forced to use in c++. However my teacher never told us the name of the naming convention. But i feel this is helpfull and readable specially when u are not using java naming conventions.
What is the semantic difference between these 3 ways of using ivars and properties in Objective-C?
1.
#class MyOtherObject;
#interface MyObject {
}
#property (nonatomic, retain) MyOtherObject *otherObj;
2.
#import "MyOtherObject.h"
#interface MyObject {
MyOtherObject *otherObj;
}
#property (nonatomic, retain) MyOtherObject *otherObj;
3.
#import "MyOtherObject.h"
#interface MyObject {
MyOtherObject *otherObj;
}
Number 1 differs from the other two by forward declaring the MyOtherObject class to minimize the amount of code seen by the compiler and linker and also potentially avoid circular references. If you do it this way remember to put the #import into the .m file.
By declaring an #property, (and matching #synthesize in the .m) file, you auto-generate accessor methods with the memory semantics handled how you specify. The rule of thumb for most objects is Retain, but NSStrings, for instance should use Copy. Whereas Singletons and Delegates should usually use Assign. Hand-writing accessors is tedious and error-prone so this saves a lot of typing and dumb bugs.
Also, declaring a synthesized property lets you call an accessor method using dot notation like this:
self.otherObj = someOtherNewObject; // set it
MyOtherObject *thingee = self.otherObj; // get it
Instead of the normal, message-passing way:
[self setOtherObject:someOtherNewObject]; // set it
MyOtherObject *thingee = [self otherObj]; // get it
Behind the scenes you're really calling a method that looks like this:
- (void) setOtherObj:(MyOtherObject *)anOtherObject {
if (otherObject == anOtherObject) {
return;
}
MyOtherObject *oldOtherObject = otherObject; // keep a reference to the old value for a second
otherObject = [anOtherObject retain]; // put the new value in
[oldOtherObject release]; // let go of the old object
} // set it
…or this
- (MyOtherObject *) otherObject {
return otherObject;
} // get it
Total pain in the butt, right. Now do that for every ivar in the class. If you don't do it exactly right, you get a memory leak. Best to just let the compiler do the work.
I see that Number 1 doesn't have an ivar. Assuming that's not a typo, it's fine because the #property / #synthesize directives will declare an ivar for you as well, behind the scenes. I believe this is new for Mac OS X - Snow Leopard and iOS4.
Number 3 does not have those accessors generated so you have to write them yourself. If you want your accessor methods to have side effects, you do your standard memory management dance, as shown above, then do whatever side work you need to, inside the accessor method. If you synthesize a property as well as write your own, then your version has priority.
Did I cover everything?
Back in the old days you had ivars, and if you wanted to let some other class set or read them then you had to define a getter (i.e., -(NSString *)foo) and a setter (i.e., -(void)setFoo:(NSString *)aFoo;).
What properties give you is the setter and getter for free (almost!) along with an ivar. So when you define a property now, you can set the atomicity (do you want to allow multiple setting actions from multiple threads, for instance), as well as assign/retain/copy semantics (that is, should the setter copy the new value or just save the current value - important if another class is trying to set your string property with a mutable string which might get changed later).
This is what #synthesize does. Many people leave the ivar name the same, but you can change it when you write your synthesize statement (i.e., #synthesize foo=_foo; means make an ivar named _foo for the property foo, so if you want to read or write this property and you do not use self.foo, you will have to use _foo = ... - it just helps you catch direct references to the ivar if you wanted to only go through the setter and getter).
As of Xcode 4.6, you do not need to use the #synthesize statement - the compiler will do it automatically and by default will prepend the ivar's name with _.