difference between a variable with and without an underscore in objective-c [duplicate] - objective-c

This question already has answers here:
How does an underscore in front of a variable in a cocoa objective-c class work?
(9 answers)
Closed 9 years ago.
In the tutorial i am following, it creates a property of an array like so
#property (nonatomic, retain) NSMutableArray *entries;
And in the implementation file and defines it defines it as...
entries = [[NSMutableArray alloc] init];
However in my program, defining like that gives me an error
"Use of undeclared identifier 'entries'; did you mean '_entries'?"
Does this affect my program?

In simple:
#property (nonatomic, retain) NSMutableArray *entries;
creates the following code for you:
An ivar called _entries and two methods
- (void)setEntries:(NSMutableArray *)entries;
- (NSMutableArray *)entries;
If you want to give the ivar a different name (e. g. entries without underscore) you have to synthesize them. But you hardly ever need the actual, just use your properties like self.entries.
The rare cases where you actually want the ivar is when you want to override the setter and getter method
- (void)setEntries:(NSMutableArray *)entries
{
_entries = entries;
// do more stuff
}

When you declare property compilator create private variable which you can access with underscore (_entries) and compilator also create setter (if you do not specify readonly) and getter. You can call getter in two ways:
[self entries] or self.entries
When you declare property you should access in it two ways:
_entries - You access your private variable directly (can be use just inside the class)
self.entries - You can access this property view setter/getter it's safe way because this method manage way how to access it (release, retain, copy, etc.)

#property (nonatomic, retain) NSMutableArray *entries; is nothing but an instance variable of name _entries. (or any other name, that you can specify while doing the synthesize)
When you do #synthesize entries, two accessor methods (setter and getter) are created for you
- (void)setEntries:(NSMutableArray *)entries;
- (NSMutableArray *)entries;
If you access it directly as _entries, then it is just changing the value of the variable.
But if you say self.entries, the accessor methods are called. The accessor methods are made according to what property type you specified, strong (or retain) copy assign atomic, say assign will just copy the value to the variable, atomic makes sure that if setter and getter are called together from different threads, getter always gets the value either prior to the start of setter or after the completion of setter.

Related

Declare instance variable nonproperty and property same name [duplicate]

This question already has answers here:
Do declared properties require a corresponding instance variable?
(6 answers)
Closed 9 years ago.
Why in many fragment code declare instance variable like and for what? what different about property and non property
#import <Foundation/Foundation.h>
#interface class1:NSObject
{
NSMutableString *currentData;
}
#property (nonatomic, retain) NSMutableString * currentData;
What you saw is an "old code"... but sometimes you still need to support old versions (e.g. 10.5).
A property is simply a couple of getter and setter (well.. it depends on the attributes you choose: e.g. readonly will generate only a getter).
But a property operates (and so it needs) an instance variable. Usually what you see in the implementation file is something like
#implementation class1
#synthesize currentData = currentData;
#end
This means create getter and setter which uses currentData as variable.
For newer version you don't need to create the instance variable and you can just type the property and synthesize statement. In the most recent language version you don't even need the synthesize statement. Automatically an instance variable named _propertyName (underscore + name of the property) is created.
BTW: sometimes you still need to make your own getter and/or setter. Classic naming convention applies (e.g. - (void)setCurrentData: (NSMutableString*)newData; for setter and - (NSMutableString*)currentData; for getter), but same rules as before for properties: if you support only the most recent OSes you can just write the #property statement and right your getter and setter by using the "underscored" variable...

do category allow addition of instance variables in its implemenation?

I am working ios6.0 sdk with xcode 4.5.2
Here is following code i used to implement a category
.h
#interface NSObject (busyMode)
#property (nonatomic,assign) BOOL busy;
#end
.m
#implementation NSObject (busyMode)
BOOL _bsy;
-(BOOL)busy{
return _bsy;
}
-(void)setBusy:(BOOL)busy
{
_bsy = busy;
}
#end
as i read along many post, it says that we cannot have instance variables in category. And so above code should not work. But as i tried it out, all was working fine.
Has there been any changes related to category or was it just luck??
As others have pointed out, you didn't add an instance variable, but a global variable which is going to be shared among all of your instances.
Categories cannot add instance variables. However, you can simulate instance variables if you absolutely need them with objc_setAssociatedObject() and objc_getAssociatedObject().
That's because you have defined a single global variable, which isn't an instance variable.
Try and instantiate two instances of this object and you will observe that each instance cannot hold a different value.
You have not added an iVar. You have defined a global variable _bsy and are accessing it in the getter/setter for the property defined by your category.
I have a macro that lets you declare "properties" in categories like this:
#implementation NSObject (AwesomeUtils)
JESynthesize(assign, NSInteger, index, setIndex);
JESynthesize(strong, NSString *, name, setName);
JESynthesize(copy, void(^)(void), completion, setCompletion);
JESynthesize(unsafe_unretained, id, unsafeObject, setUnsafeObject);
JESynthesize(weak, id<UITableViewDelegate>, delegate, setDelegate);
JESynthesize(strong, NSString *, readonlyID, changeReadonlyID);
// …
#end
I say "properties" with quotes because you can use them even without the #property declaration. The macro also works around to support weak.
You can check the implementation here (the header files are at the bottom):
http://nspicks.com/2013/12/15/cleaner-properties-implementation-in-categories/

Objective C - changing a local variable w/ setter and w/o setter [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Difference between self.ivar and ivar?
In Objective-C, what's the difference between [self setVariable: newStuff] and variable = newStuff?
When you have a class with a variable
#property (nonatomic) NSInteger num;
and you want to change the variable, typically you can do
[self setNum: newNum]
but you can also do
num = newNum
I know if you declare the variable readOnly, you can't use the first method to change it, but what's the concept behind it? Is it just because the second method with the setter can be called outside of its own class? Like if the class's instance was called 'sample'.
[sample setNum: newNum]
but then if you are changing the variable inside the class, either way is fine?
In Objective-C, what's the difference between [self setVariable:
newStuff] and variable = newStuff?
To be absolutely pedantic, one of them assigns the variable property the value in newStuff, whereas the other one assigns the value of newStuff to the iVar variable, but what I think you had in mind was a comparison between [self setVariable:
newStuff] and self.variable = newStuff. In that case, nothing is different, the compiler will expand case 2 out to case 1.
I know if you declare the variable readOnly, you can't use the first
method to change it, but what's the concept behind it? Is it just
because the second method with the setter can be called outside of its
own class? Like if the class's instance was called 'sample'.
readonly variables are important in cases where certain properties are private to the implementation of a class, but should be visible to other classes.
For example, if I were writing a Stack, I might want to expose the count of the number of items on the stack, but it would be a very bad idea for other classes to be able to write to the count variable. If I weren't smart and were using something like a count variable, I would want to be able to adjust the count of the semaphore internally (meaning you need it to be internally readwrite), so I declare a visibly readonly property so other classes can get it, but declare it internally readwrite so I can modify it:
//.h
#interface CFExampleStack : NSObject
#property (nonatomic, assign, readonly) int count; //readonly
#end
//.m
#interface CFExampleStack ()
#property (nonatomic, assign) int count; //readwrite
#end
Is it just because the second method with the setter can be called outside of its own class?
Well, that depends on how your instance variable is declared. By default, instance variables are #protected, i. e. they can be accessed from within the class and its subclasses only. However, if you explicitly declare an ivar as #public, then you can access it outside the class, using the C struct pointer member operator ->:
obj->publicIvar = 42;
However, this is not recommended, since it violates encapsulation.
Furthermore, if you use a custom setter method, then you have the opportunity to do custom actions when a property of an instance is updated. For example, if one changes the backgroundColor property of a UIView, it needs to redraw itself in addition to assigning the new UIColor object to its appropriate ivar, and for that, a custom setter implementation with side effects is needed.
Additionally, there are retained ("strong") and copied properties in case of instance variables that hold object. While writing a setter for a primitive type such as an integer is as simple as
- (void)setFoo:(int)newFoo
{
_foo = newFoo;
}
then, in contrast, a retained or copied property needs proper memory nanagement calls:
- (void)setBar:(Bar *)newBar
{
if (_bar != newBar) {
[_bar release];
_bar = [newBar retain]; // or copy
}
}
Without such an implementation, no reference counting would take place, so the assigned object could either be prematurely deallocated or leaked.
One more important difference...
Whenever you use self.prop KVC comes into play and you can observe the changes in the object, while _prop bypasses it.

Is it necessary to specify #property objects within the brackets of an Objective-C #interface? [duplicate]

This question already has an answer here:
Closed 11 years ago.
Possible Duplicate:
Properties declared as instance variables too?
Let's say I have an objective c class interface like:
#interface {
NSString * someString;
}
#property (nonatomic, retain) NSString * someString;
with an #implementation that #synthesizes the string and does some other stuff.
What I'd like to know is, whether it's necessary to have that NSString * someString object pointer declaration within the brackets at all. (As an aside, is there a specific term for the space between the brackets where variables are defined?) It seems like the code will work fine if I omit the NSString * someString declaration, and the #property line has all the same information about type. So, if it's not necessary to have the variable declaration, why does the option exist at all? What happens if you have conflicting types in the variable declaration and the #property declaration?
For the most part, it shouldn't be necessary, since #synthesize will create a variable if it is not predefined. Also, you can create your own variable with #synthesize as well, using:
#synthesize aVar = _theVariableName;
That will create a getter method (aVar), a setter method (setAVar), and an instance variable named _theVariableName which you can use for memory management purposes.
However, I don't know if #dynamic will do the same, and if implementing your own setters and getters, I think you need the declaration...

Semantic Issue: Property's synthesized getter follows Cocoa naming convention for returning 'owned' objects

I'm currently using the iOS 5 SDK trying to develop my app.
I'm trying to make an NSString a property, and then to synthesize it in the .m file (I have done this before with no issues). Now, I came across this: "Semantic Issue: Property's synthesized getter follows Cocoa naming convention for returning 'owned' objects."
This is my code:
.h
#interface ViewController : UIViewController {
NSString *newTitle;
}
#property (strong, nonatomic) NSString *newTitle;
.m
#synthesize newTitle;
Does anyone have a clue how I could fix this?
Thanks!!
My guess is that the compiler version you’re using follows the memory management rules for declared properties, too — more specifically, for declared properties’ accessors:
You take ownership of an object if you create it using a method whose name begins with “alloc”, “new”, “copy”, or “mutableCopy”.
A property named newTitle, when synthesised, yields a method called -newTitle, hence the warning/error. -newTitle is supposed to be a getter method for the newTitle property, however naming conventions state that a method whose name begins with new returns an object that’s owned by the caller, which is not the case of getter methods.
You can solve this by:
Renaming that property:
#property (strong, nonatomic) NSString *theNewTitle;
Keeping the property name and specifying a getter name that doesn’t begin with one of the special method name prefixes:
#property (strong, nonatomic, getter=theNewTitle) NSString *newTitle;
Keeping both the property name and the getter name, and telling the compiler that, even though the getter name starts with new, it belongs to the none method family as opposed to the new method family:
#ifndef __has_attribute
#define __has_attribute(x) 0 // Compatibility with non-clang compilers
#endif
#if __has_attribute(objc_method_family)
#define BV_OBJC_METHOD_FAMILY_NONE __attribute__((objc_method_family(none)))
#else
#define BV_OBJC_METHOD_FAMILY_NONE
#endif
#interface ViewController : UIViewController
#property (strong, nonatomic) NSString *newTitle;
- (NSString *)newTitle BV_OBJC_METHOD_FAMILY_NONE;
#end
Note that even though this solution allows you to keep newTitle as both the property name and the getter name, having a method called -newTitle that doesn’t return an object owned by the caller can be confusing for other people reading your code.
For the record, Apple have published Transitioning to ARC Release Notes, in which they state:
You cannot give a property a name that begins with new or copy.
They’ve already been notified that their statement is not quite accurate: the culprit is the getter method name, not the property name.
Edit 17 Jan 2015: I’ve just noticed a recent commit to Clang that suggests option 3 above (using objc_method_family(none)), including a fix-it, for the general case where a property name matches one of the special method family prefixes. Xcode will likely incorporate this change eventually.
Unacceptable Object Names
newButton
copyLabel
allocTitle
Acceptable Object Names
neueButton
mCopyLabel
_allocTitle
#arc #auto-synthesized #xcode-4.6.1
** EDIT **
Apparently you can't use mutableCopy either.
The name of the member starting with new is what triggers the warning. Change the name to editedTitle and the warning will go away. I was unable to find documentation confirming this but through testing was able to determine that member variables that begin with 'new' aggravate the compiler.
ARC does not allow to use "New...." in property name. but you can use "newTitle" by changing getter name.
#property (nonatomic, strong, getter=theNewTitle) NSString *newTitle;
It doesn't look like what Bavarious was suggesting was what you wanted to do. All you want to do is declare an instance variable NewTitle and then synthesize the property. We used to have to declare the instance variable and property. No more.
Now, I believe the right way of doing this is the following:
.h
#interface ViewController : UIViewController
#property (nonatomic, strong) NSString *newTitle;
.m
#synthesize newTitle = _newTitle; // Use instance variable _newTitle for storage
The instance variable for the property newTitle is synthesized. You don't want your instance variable to be the same as your property - too easy to make mistakes.
See Example: Declaring Properties and Synthesizing Accessors
In CoreData if you use "new..." in attribute (compile normally) it will crash randomly with a "bad access" exception.
There is no crash log and the line shown with the "All Exceptions Breakpoint" will not help you at all.
Writing a setter manually with the name same as the property's removed this warning.
NS_RETURNS_NOT_RETAINED is used to solve the naming problem.
#property (nonatomic, copy) NSString *newTitle NS_RETURNS_NOT_RETAINED;
We can find its definition as follows:
#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))
The 'ns_returns_not_retained' attribute is the complement of 'ns_returns_retained'. Where a function or method may appear to obey the Cocoa conventions and return a retained Cocoa object, this attribute can be used to indicate that the object reference returned should not be considered as an "owning" reference being returned to the caller. The Foundation framework defines a macro NS_RETURNS_NOT_RETAINED that is functionally equivalent to the one shown below.
Besides the issue that you should/can't use "new" in front of you property names, let say one more thing: Try to avoid "new" in front of names in general. "New" is dependent on time. Currently it is new for you, but some time later you maybe want to implement something new again. So using "new" in names is always bad. Try to think this way: In the programming world, "new" is always creating something: a new instance of something.
In your case when you want to assign a different title then the current name your property titleReplacement.
One more thing: Try to name functions and methods with the verb first, like setSomething or getSomething.
But in properties try to name the object first, like heightMinimum, heightMaximum, etc. -> when you use your inspector when you are coding, you always looking for objects. Try it out. ;-)
try this:-
#property (nonatomic,retain) NSString *newTitle;