Is it allowed to duplicate variable name in same class? - ios

I have a block of source code getting from Github. It looks like:
Header file
#interface VTDUpcomingDisplayData : NSObject
#property (nonatomic, readonly, copy,) NSArray* sections; // array of VTDUpcomingDisplaySection
+ (instancetype)upcomingDisplayDataWithSections:(NSArray *)sections;
#end
Implementation file
#import "VTDUpcomingDisplayData.h"
#interface VTDUpcomingDisplayData()
#property (nonatomic, copy) NSArray* sections;
#end
#implementation VTDUpcomingDisplayData
+ (instancetype)upcomingDisplayDataWithSections:(NSArray *)sections
{
VTDUpcomingDisplayData* data = [[VTDUpcomingDisplayData alloc] init];
data.sections = sections;
return data;
}
This block code has two variable name called 'sections' but builds successfully. I have two questions:
First of all, I do not understand why this is allowed to happen?
Second, how to call exact the variable I want in source code?

It's normal in Objective-C, called override property attribute or redeclaring a property. You can declare a property is readonly in interface, and make it's readwrite (There’s no need to specify the readwrite attribute explicitly, but in this case You better write it) in implement.
Here's Apple document about redeclaring a property in class extension
Class extensions are often used to extend the public interface with
additional private methods or properties for use within the
implementation of the class itself. It’s common, for example, to
define a property as readonly in the interface, but as readwrite in a
class extension declared above the implementation, in order that the
internal methods of the class can change the property value directly.
First of all, I do not understand why this is allowed to happen?
Just because it's normal behavior in Objective-C
Second, how to call exact the variable I want in source code?
It's just once property, You can access it as readwrite in internal method. But in other class it's still readonly

Both declarations refer to the same property (and underlying instance variable).
However, the properties are declared differently in the header and the implementation. In the header, which defines the interface to be used by callers of this object, the property is declared readonly. In the implementation of the class the same property is missing the readonly attribute, i.e. it is read/write.
This is to allow the implementation of the class read and write access to the property but limit users of the class to only read from the property. Everybody is accessing the same property (instance variable), the only difference is the access rights of the different callers.

Related

Does `nonatomic` makes sense in a `readonly` declared property (including class property)?

EDIT: This question applies to normal declared properties as well (not only to class properties)!
Original Post:
Lets say I have the public class method sharedInstance which is currently implemented as a getter method:
#interface MyClass
+ (instancetype)sharedInstance;
- (void)doSomething;
#end
#implementation MyClass
+ (instancetype)sharedInstance {
static MyClass *shared = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
shared = [[MyClass alloc] init];
});
return shared;
}
#end
Accessing this method in Swift 3.0 would look like this: MyClass.shared().doSomething()
So to make it more swifty we should change the class method to a class property (new in Xcode 8. but actually I can't find it in the Apple Docu, only in WWDC 2016 video)
#interface MyClass
#property (class, nonatomic, readonly) MyClass *sharedInstance;
- (void)doSomething;
#end
// implementation stays the same
Now in Swift code: MyClass.shared.doSomething()
So does nonatomic/atomic property modifier (don't know the exact term) even makes sense for a getter method which I implement myself in objc?
The atomic/nonatomic modifiers have no effect in your case, for multiple reasons.
The main reason is that atomicity keywords affect only generated code (i.e. synthesized accessor methods). When you declare a #property in your interface and then implement it with a method (or method pair) in your implementation, the compiler isn't generating code, so your atomicity keyword is ignored.
There are a few ways to get to this situation, and you're triggering a couple of them:
First, you have a class property. The compiler can't synthesize accessors or storage for class properties — which means no code generation, so atomicity doesn't apply.
Second, in most common uses of readonly properties, the #property declaration is backed by a manually implemented getter method — which means there's no code generation and thus atomicity doesn't apply.
(Note you can also have instance properties declared as readonly in a public interface and synthesized due to a private readwrite redeclaration in your implementation. In that case, not only does atomicity apply, you have to make the atomicity keywords match between your public and private declarations. You can also synthesize just a getter and work directly with the backing ivar in your implementation.)
Because specifying either atomic or nonatomic for this property does nothing either way, you're free to just leave atomicity keywords out of your declaration entirely. (The compiler will assume atomic, but as noted that assumption has no effect.)
It makes perfect sense. The declaration of a property gives the user of the class information. An user of the class is allowed to expect from the – synthesized or manual – implementation, what you tell in the declaration. The user cannot even know, whether it is synthesized or not.
If you implement the getter (or whatever accessor) yourself, you should reflect the atomicity of your implementation in the declaration of the property. If you have a non-atomic implementation, you should add that to the declared property.

is there a better way to write the property in OC?

i have property like this:#property (nonatomic, assign, readonly) CGRect frame;in the example.h file,i think this statement is to tell other class that the frame property is readonly and it also tell the compiler do not need to synthesize a setter method.
is that right to say that the class itself can use the instance variable _frame(the self.frame still can not use) in the .m file? if so,is there a better way to use this instance variable _frame? redeclare this property to readwrite in the class extension or redeclare the instance variable in class extension like this(i have found many guys write like this,but i do not understand what is the benefit of doing so?):
#interface example () {
CGRect _frame;
}
#end
#implementation example
or i just need do nothing?
My understanding about property as follows:
1.program find name of property in class of receiver when you take dot operator(.).
Like this: tt.frame (example* tt = [[example alloc] init];)
2.Then program find relationship between name of property(binding with synthesized method same name as name of property) and instance variable.
The way for that is: #synthesize frame=_frame;
(frame is name of property,_frame is instance variable. Binding name of property and instance variable.If you don't do like this,compiler will provide a instance variable (frame,then modify this frame, not _frame you designed.)when you choice 64-bit environment.Or compiler will give you a warning, if you choice 32-bit environment)
3.Call method for the real instance variable.

Objective-C member variable vs property in source file

I understand the difference between member variable and property in Object-C, but there is one thing make me confused. See the following code.
test.h
#interface test : NSObject
#end
test.m
#interface test()
{
NSString *memberStr;
}
#property (nonatomic, strong) NSString *properyStr;
#end
As showed, the memberStr and propertyStr can't be see by outside. I want to know what is the difference between them. Because I don't how to chose the solution when i want to use local variable.
Thanks!
properyStr will have the getters and setters generated automatically.
you can define custom setter for propertyStr as below. When you use self.propertyStr, it will create a default object for you. It will be useful for initialising objects like NSMutableArray, NSMutableDictionary etc.
- (NSString *)properyStr
{
if(_propertyStr == nil)
{
_propertyStr = #"";
}
return _propertyStr;
}
memberStr will not have these options.
I understand the difference between member variable and property in Object-C
I'm not sure that you do.
A member variable is a variable that's visible only within the scope of instance methods.
A property is some attribute of the class that can be set or get. The compiler will write appropriate getters and, optionally, setters, and will organise storage for itself, unless you override any of those things.
Both member variables and properties can be declared either in the #implementation or in the #interface.
A member variable can never be accessed directly by unrelated classes, regardless of where it was declared. If it's in the #interface then it can be accessed by subclasses.
A property can always be read and, optionally, written by any other class, regardless of where it was declared. External classes can use the key-value coding mechanism even if the #property isn't visible to them.
Questions you may therefore be likely to ask:
Q) Why would I put a member variable into the #interface?
A) It's unlikely you would. It will expose it to subclasses but usually wanting to do so is a design flaw. However, in olden times you had to put all member variables into the #interface for reasons of how the old Objective-C runtime worked. So older code and stuck-in-their-ways programmers will still sometimes follow this pattern.
Q) Why would I declare a property visible only to the #implementation?
A) It's unlikely you would. However in olden times this was the only way to create member variables that weren't visible in the #interface so was the way people did most member variables for a brief period. Similarly, you could declare something, say retain, then use the getter/setter and assume correct memory management was going on, so it acted as some syntactic sugar in the days before ARC was introduced. As with the previous answer, there are therefore some people who still do so through habit and some code that still does so on account of being older. It's not something you'd often do nowadays.
EDIT: a better summary: properties adjust your class interface. Member variables adjust its implementation. In object-oriented programming you should be thinking of the two things as entirely disjoint.
One of the main purposes of object-oriented programming is to have a bunch of discrete actors that say "I can do X" with exactly how they do it being nobody else's business.
A property says what a class can do. A member variable is for the benefit of how the class does it.
Semantically they're completely separate issues.
First of memberStr is an instance variable or ivar.
There is no need to have memberStr any more if you have a property setup for this all you need is.
#interface test()
#property (nonatomic, strong) NSString *properyStr;
#end
The reason for this is that the ivar will be automatically created for you along side the setter and getter methods.
The only difference between declaring the property in the implementation files (.m) interface over the interface file (.h) is that it will be private to this class only. There are many advantages for having this such as maybe you don't want anything outside of the class to know about it but you want the property to be in scope for this class still. One thing that they are used for in this manner is when you have a readonly property declared public but you still want the setter to be in scope for this class. So you may have something like
.h
#interface MyObject : NSObject
// Other classes can see this property as it is public however they can only see
// it's getter and not the setter
#property (nonatomic, readonly) NSString *firstName;
#end
.m
#interface MyObject()
// But we still want to use the setter for this class only.
#property (nonatomic, strong) NSString *firstName;
#end
Otherwise except for being private to that class only; having the property in the implementation file (.m) will be the exact same as having it in the interface file (.h) they will act and do the same thing.

iOS Basics: private property, public setter/getter

I've been reading the tutorials and I'm right now designing the model's architecture, and since I'm new to Objective-C, I'm not sure if the standards are like Java where you have public setter/getter and private attribute. This is 1 question I'd like to ask.
If the standards are so, declaring private properties are done in the *.m file #interface, but how do I #syntetize a setter/getter and how do I call them from outside: is it like [object SetProperty:property] ?
If the standards are different, can I get an example of a model class?
Thanks in advance.
A property is essentially a promise that a class provides certain accessor methods. For example:
#property(strong, nonatomic) Foo *foo;
is a promise that the class provides -foo and -setFoo: methods. So, if you want the accessors to be public, declare the property in your class's public interface (i.e. in the header file) and be done with it.
It's true that the instance variable that backs that property (_foo, unless you specify a different name) will then be accessible, but it's very poor form to access another object's instance variables directly. Many things in Objective-C are governed by convention and that's generally enough to avoid problems. Also, a given property doesn't have to be backed by any instance variable at all: a property like fullName might be computed from other properties like firstName and lastName, so there's good reason beyond mere convention for clients to avoid accessing ivars directly.
The common approach if you want to give access to your attribute is to use the keyword #property in the .h file of your class to define a property. This will automatically define a setter and a getter and you don't need to synthesise your property as of Xcode 4.4.
Your private attribute will be accessible within your .m file and will have the name of your property with "_" as a prefix by default.
You can create a private property and create public setter/getter method of your own. From this method you can assign or retrieve the value back.
#interface Person : NSObject
-(void)setTheName:(NSString *)fullName;
-(NSString *)theName;
#end
Implementation file:
#import "Person.h"
#interface Person()
#property(atomic) NSString *fullName;
#end
#implementation Person
-(void)setTheName:(NSString *)fullName{
self.fullName = fullName;
}
-(NSString *)theName{
return self.fullName;
}
#end
In the above is private however you can check the selector still exists(but throws a warning)
if ([p respondsToSelector:#selector(setFullName:)]) {
[p performSelector:#selector(setFullName:) withObject:#"Anoop"];
}
NSLog(#">>>> %#",[p theName]);
Output will be :
>>>> Anoop
However it is seldom required to set any private property from outside. If that is the requirement we can make the property public.
Well it is true that Objective-C uses another terminology than most of the other languages like Java. If I get what you're asking, if you want a property to be directly available outside the class, the property must be declared in the .h file. However if you want to hide the implementation of your code, you can declare a property in the .m file and provide setters/getters to the outside world just returning the information you want to be visible.
The #synthesize clause is to me a simpifier. By synthesizing a property the getter/setter will be automatically implemented and you don't need to do it yourself.
Does this answer your question ?
Understand that declaring a property causes the compiler to create accessor for you . so if i require a pseudo private property personally I declare it in the implementation, if i need pseudo public property i declare it in the header. public getter / private setter can be handled as indicated below. There is no need to create your own setters and getters prefer using an attribute as it saves writing setters/getters ;
in the header (.h)
#interface Person : NSObject
#property (nonatomic, readonly) NSString *fullName;
#end
in the implementation file (.m)
#import "Person.h"
#interface Person()
#property (nonatomic, readwrite) NSString *fullName;
#end
#implementation Person
... whatever this class does
// self.fullName = #"John Doe";
#end

IOS: property and self [duplicate]

This question already has answers here:
iOS: Usage of self and underscore(_) with variable [duplicate]
(3 answers)
Closed 8 years ago.
When I declare an NSString I simply do:
NSString * my_string; (in interface of my .h)
If I want to allow access to this string from other classes I add a property in this way
property (nonatomic, strong) NSString *my_string;
and I write the synthesize
synthesize my_string; (in .m)
Now I have some question about:
If I use a property, must I also use the simple declaration in interface?
If I use my_string as a property, must I always use self. before?
If I use a property, is it necessary to write #synthesize for each? (because I saw that sometimes it's not necessary.
If I use a property, must I also use the simple declaration in interface?
No, generally you just want to use the #property (it will quietly add an instance variable for you).
If I use my_string as a property, must I always use self. before?
You don't need to but you should. Using self. calls the accessor method to get the variable contents. Not using self. accesses the instance variable directly. So, if you add a custom accessor in the future you will need to refactor.
Often you will reuse the same variable multiple times. In this case, call self., but use it to set a local variable that you then use throughout the method (in this way the accessor is only called once).
If I use a property, is it necessary to write #synthesize for each? (because I saw that sometimes it's not necessary.
No, the compiler will add:
#synthesize propertyName = _propertyName;
for you, and that is a good approach to follow (separating the property name from the instance variable name).
NO
NO, using self. will execute accessor method, you can use it with name _my_string and then you'll access the variable directly. If you want a different variable name for your property then you must use synthetize with that name
NO, xcode will synthetize it automatically with the variable named _my_string
It's becoming more and more appropriate to use properties in all cases anymore. You can declare "private" properties inside a header extension inside the .m file if you don't want to expose them to outside classes. Say you have a property called name in the .h file:
#property (nonatomic, strong) NSString *name;
Users of this class can access the name property by saying theVariable.name, inside your .m file you need to access this property with self.name. However you can access the ivar like so:
_name = #"John Smith"
This will skip the property and go directly to the ivar. In this case if you had an overriden setter it won't be called.
You no longer need to synthesize properties. Xcode will automatically provide this:
#synthesize name = _name;

Resources