This question already has answers here:
How to make a real private instance variable?
(7 answers)
Closed 8 years ago.
How exactly should attributes be declared if they are needed to be private and the language supports automatic getter/setter method creation?
Is the only way to override the automatically created getter or setter as needed?
In the top of the .m (implementation) file:
// Private category on your class, declared at top of implementation file.
#interface MyClass ()
#property (nonatomic, copy) NSString * privateString;
#end
#implementation
...
#end
These "private properties" are visible only within your implementation.
Please note that ObjC has no facility for runtime access restriction. Other objects can still call your private getters and setters if they want to (although this will generate compiler warnings).
Related
This question already has answers here:
When should I use #synthesize explicitly?
(7 answers)
Closed 8 years ago.
I am having some difficulty understanding what objects are supposed to be synthesized. For example:
#interface DoSomething : UIView
#property (strong, nonatomic) UIColor *frameColor;
#property BOOL toggleScrollability;
- (void) changeBackgroundColorOfView;
#end
In the .m file, which of these three items should be synthesized? Is there any disadvantage if I try and synthesize them all? In general, what is the rule of thumb for what objects you are supposed to synthesize?
The first two are properties; the third is an instance method. #synthesize applies only to properties.
However, if you're building for iOS 6 or newer, you don't need to synthesize at all. The compiler has handled this automatically for the last few years now.
You can only synthesize properties, so you won't be able to write #synthesize changeBackgroundColorOfView.
Since XCode 4 I think, you don't have to use #synthesize anymore. The compiler automatically add it when it needs to be and you can access it by adding a _ before the name of your property.
In your example, you will access the frameColor property as _frameColor if you are in the DoSomething class, doSomethingInstance.frameColor if not.
But, you can always add it yourself if you want to rename your property for internal stuff.
See Apple's reference.
This question already has answers here:
Varieties of #interface declarations, some with parentheses
(3 answers)
Closed 8 years ago.
I'm looking at a .h file for an Objective-C class and I see multiple interface declarations in it and I am unsure as to what the differences are and what they mean.
First I see
#interface TAModel : NSObject
Which I recognize. TAModel is the class and NSObject is it's super class. What I'm confused about is further down I see another interface declaration:
#interface TAModel (Protected)
Also inside another .m file (unrelated to the first two) I have seen:
#interface TAWorker (Private)
I was wondering what the second two mean, what they are doing. As far as I know with objective-c there is no true protected visibility between classes.
It's creating a category class in which they're putting their protected/private members. The usual idiom is just to create a class extension (so you'll often see #interface Foo (); the difference here is that you can also declare more fields, not just properties and methods) in the .m file.
Neither way of doing this truly protected or private as you can still technically get at the things declared there by casting to id first or through one of the performSelector: methods. But it's pseudo-private because you don't publish the interface publicly if it's not in the .h file.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
iOS: must every iVar really be property?
I just read a book that said that modern convention is not to declare any ivars at all in your .h file between curly braces, and instead to make everything properties.
I want to make sure this is true even in trivial cases. I am making a class where there is a BOOL named "recording" which says whether the device is currently recording some video. This isn't something that other classes need, and my incline is to just put it as a BOOL in the header then refer to it in the .m file in the 2 spots where it is needed.
However, I also want to do things the accepted, right way. But I don't see why I make it a public property?
What you read is wrong, plain and simple.
Modern convention is to skip ivars when there is a corresponding property that can synthesize them. Additionally, with recent versions of LLVM it is possible to move your ivars to your implementation file (as #DrummerB has already mentioned) so that the header contains no ivars. That's considered good practice because it doesn't expose internal workings of the class.
But have no ivars at all and a property for everything that was an ivar? Nope, not normal Objective-C.
Your book is right (and wrong). Don't declare ivars in your headers anymore. That's only supported for compatibility reasons. But also don't declare properties for private variables.
If you want do declare a private ivar that other classes don't need to use, declare them in your implementation file:
// MyClass.m
#implementation {
BOOL recording;
}
// methods
#end
I recommend to not use ivar at all. Instead you can create a class extension in which you will declare properties that has to be hidden:
#interface MyClass ()
#property (nonatomic, assign) BOOL recording;
#end
You could use something like
#interface G4AppDelegate ()
#property (nonatomic, assign) BOOL recording;
#end
To make an "internal" property.
Or as the other answer states use an iVar in your implementation
Some books explain that you should only use getter and setter to access your ivar, even if they are private. This is a little too psychotique to me.
Before clang, u should have to create category on class and use synthesizer to make ur ivar private. like this:
#interface AppDelegate ()
#property(nonatomic, assign)int aValue;
#end
// + #implement AppDelegate
// #synthetise aValue;
that could be annoying since sometime u need some simple ivar, without any getter/setter control. And u're adding code where there is no need.
Now with clang you can put ur ivar directly on implementation file like this in ur code:
#interface AppDelegate (){
int _aValue;
}
#end
And u're hiding private ivar out of the scope the header.
Note, u can't compile this with gcc.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
iOS: must every iVar really be property?
I really would appreciate if somebody could explain to me why some properties are defined in the interface statement and some as #property ones.
#interface PlacesParser : NSObject
{
NSMutableArray *arrPlaces;
TBXML *tbxml;
}
#property(nonatomic,retain) NSMutableArray *arrPlaces;
-(void)loadRecords:(NSString *)records;
-(void)traverseElement:(TBXMLElement *)element;
#end
In my example we got "arrPlaces" as #property
and "arrPlaces" within the interface.
The thing in the interface is not actually a property, it is just a plain old instance variable. The #property statement is what makes it a property (giving you the setters and getters). You used to need both, but you don't anymore. If you want your field to be a property with those generated methods, you can leave out the initial field declaration.
What is the difference between ivars and properties in Objective-C
This thread really opened my eyes. Great explonation to my question.
This question already has answers here:
Must every ivar be a property?
(4 answers)
Closed 9 years ago.
Lately, it seems that explicitly declared instance variables in Objective-C are considered a thing to avoid, with the preference being to use "private" properties, i.e., properties declared in a class extension in the .m file.
The last example of this is the WWDC '12 presentation on advances in Objective-C.
What I haven't been able to find is a rationale for this preference, and I have searched a lot. It obviously provides a sort of solution to the fragile base class problem, but that was already solved with Objective-C 2.
Is there some crucial piece of documentation that I have missed, or is there a simple explanation that a kind soul could provide here?
You mean this?
#interface Foo : NSObject {
float bar;
id baz;
}
If those instance variables are not a part of the public interface, you will do better to move them into the implementation file, either as declared properties in a class extension or to the #implementation block:
#interface Foo ()
#property(assign) float bar;
#property(strong) id baz;
#end
…or:
#implementation Foo {
float bar;
id baz;
}
This way the public interface declared in the header stays simple and changes in the implementation won’t force a recompilation of all the source files that import the header.