Need help trying to use #property in Objective-C - objective-c

New to Objective-C (and programming for that matter), so please don't be too harsh if this question is very basic.
Apart from my main.m class, I have a Student.h and Student.m class, which I created. I am trying to avoid using many getters and setters for future projects, and if I'm correct, #property can help me with that. My basic code that works is this:
Student.h:
#import <Foundation/Foundation.h>
#interface Student : NSObject{
NSString *name;
int age;
}
//setters
- (void)setName:(NSString*)fName;
- (void)setAge:(int)newAge;
//getters
- (NSString*)getName;
- (int)getAge;
#end
Student.m:
#import "Student.h"
#implementation Student
- (void)setName:(NSString*)fName {
name = fName;
}
- (void)setAge:(int)newAge {
age = newAge;
}
- (NSString*)getName {
return name;
}
- (int)getAge {
return age;
}
#end
Can I use #property to have something like this, which would avoid using getter and setter methods? Or do I understand it all wrong?
#import <Foundation/Foundation.h>
#interface Student : NSObject{
}
#property int age;
#property NSString *name;
#end

Few things:
In Objective C you don't use get prefix for getters. You should use either plain name or with 'is' prefix for boolean properties. (Objective C conventions reference)
You really won't avoid using getters and setters. #property notation just defines them for you (maybe with some additional behaviors like copying the value instead of assigning it). It's just the matter of . notation. Underneath it's using getter/setter methods. Here you have a bit more on properties (Objetive C properties reference).
You should define your NSString property as (copy). It's much better to have as if you change it somewhere else it will affect this object (and probably you want to avoid that).

Are you coming from Java perhaps?
Yes, Objective-C used to require getters and setters to be written out laboriously by hand. Nowadays if you use #property and don't go out of your way to do anything else then a suitable instance variable and an appropriate getter and setter will be generate for you.
So the following is a complete class with usable properties, accessible either via traditional setName:/name-style setters and getters or via the dot notation (which calls the setters and getters despite looking like a C struct access:
#interface Student : NSObject
#property int age;
#property NSString *name;
#end
/* ... */
#implementation Student
#end
Also as a general encapsulation / data-hiding comment, notice that Objective-C has long ago been modified so that instance variables can be declared in the [unpublished] #implementation rather than the [published] #interface. On a technical level it was all to do with the ABI and the fragile base class problem, neither of which haunts the modern runtime.

Related

The Field between Objective-c and Java, and I don't understand the #property and instance variable

From the developer that started to learn objective-c two days ago, I don't understand the difference between the following two methods :
1.
#interface Person : NSObject
#property NSString *firstName;
#property NSString *lastName;
#end
2.
#interface Person : NSObject{
NSString *firstName;
NSString *lastName;
}
#end
Using Java-Language,we define two String Field:
class Person extends Object{
(public/private/protected) String firstName;
(public/private/protected) String lastName;
}
I want to know which one(between 1 and 2) has same meaning with the Java code above.
Very thanks for #iamyogish #Popeye,if my answer is right i will correct both of you.
After read the eBook: Objective-C 2.0 Essentials,I learned that(if it is not right,you tell me. ):
#interface Person : NSObject
#property NSString *firstName;
#property NSString *lastName;
#end
this is equivalent to the Java Code:
class Person extends Object{
private String firstName;
private String lastName;//In fact:private should be protected
//setter and getter.
//you can use ecplise tool to generate setter/getter method automaticly
}
As you can probably imagine, having to write these methods for large numbers(1000 or more.)of complex classes will ultimately prove to be time consuming. Objective-C provides synthesized accessor methods,so what you should is use of the #property and #synthesize directives.if you write your code like this:
#interface Person : NSObject
NSString *firstName;//note that the default access level is protected.
NSString *lastName;
#end
Unfortunatly, you need to provide methods that can access instance variables,such as(you can define the name of the function by yourself)
-(NSString ) getFirstName;
-(NSString ) getLastName;
-(void) setFirstName:(NSString * name);
-(void) setLastName:(NSString * name);
In addition to this,if the #property and #synthesize directives are used,you can access instance variables like C++/JAVA syntax dot notationsuch as:
NSString * firstName= [[Person alloc] init].firstName;
Note that: A key point to understand about dot notation is that it only works for instance variables for which synthesized accessor methods have been declared.
The access level for instance variables is specified in the #interface section of the class declaration using the #protected, #private and #public directives.
#interface Person : NSObject
#public
NSString *firstName;//note that the default access level is protected.
NSString *lastName;
#end
When accessing a public instance variable from another class or any other code in a methods or function, the -> pointer operator notation is used. So you can access the Public Filed in C++/C like:
[[Person alloc] init]->firstName = "your first name";
Another question is:
#interface Person : NSObject
#property NSString *firstName;
#property NSString *lastName;
#end
is is equivalent to:
#interface Person : NSObject{
NSString *firstName;
NSString *lastName;
}
#property NSString *firstName;
#property NSString *lastName;
#end
or not? and ivar is equivalent to instance variable or not?
Lets start with (2)
#interface Person : NSObject
{
NSString *firstName;
NSString *lastName;
}
#end
In this case firstName and lastName are know as ivars or Instance Variables for me I don't generally declare ivars. Some developers now say that you shouldn't put these in the #interface declaration for two reason.
It exposes details about the implementation to users of the class, this will lead other developers who or using and in some cases yourself to rely on implementation details that should be available to them.
Some developers believe that putting these in the #interface can make compile times significantly longer.
Most developers believe that the best way to implement an ivar is within the #implementation where braces are being used like:
#implementation Person {
NSString *firstName;
NSString *lastName;
}
The theory behind why we put them here is because theoretically they are declared private, preventing anyone from knowing about them except the developer who created the class. This will resolve all other developers from messing around with things they shouldn't.
The equivalent to this in Java is just as simple as private String firstName;
Now lets take a look at (1)
#interface Person : NSObject
#property NSString *firstName;
#property NSString *lastName;
#end
Technically #properties need only be used when the property needs to be accessible from other classes, but many developers prefer to use these over ivars as it makes them easier to use, and in new versions of xcode the ivars for these properties are declared automatically in the background.
By declaring a property you are basically automatically generating the getters and setters for these properties. In earlier versions of xcode you did have to #synthesize but there is no need for this anymore. So declaring the two properties firstName and lastName this will generate in the background
- (void)setFirstName:(NSString *)aFirstName
{
self.firstName = aFirstName;
}
- (NSString *)firstName
{
// Note in objective-c we don't generally use `get`
return self.firstName;
}
- (void)setLastName:(NSString *)aLastName
{
self.lastName= aLastName;
}
- (NSString *)lastName
{
// Note in objective-c we don't generally use `get`
return self.lastName;
}
When it comes to comparing this to Java this is near enough the same as
private String firstName;
public void setFirstName(String aFirstName) {
this.firstName = aFirstName;
}
public String getFirstName() {
return this.firstName;
}
We create out instance variable the same way we would do it as if it was a normal ivar but there is nothing to say create my setters and getters in java so we have to do that ourselves. Note that the ivar here in java is still private it is the getters and setters that we are opening up to others.
There is a sort of third option that you have missed as well. Due to the conventions in objective-c what would happen with a #property for a bool?
We have it declared like
#property (nonatomic) BOOL personForObject;
in objective-c when it comes to bools the getter is slightly different in name. Whilst we are happy with the synthesized setter of
- (void)setPersonForObject:(BOOL)aPersonForObject
{
self.personForObject = aPersonForObject;
}
we aren't happy though with the getter, when it comes to bools the getters should start with is so personForObjects getter should be isPersonForObject but the synthesize doesn't know this so will automatically generate the getter the other way. So we need to tell it in the property declaration like
#property (nonatomic, getter=isPersonForObject) BOOL personForObject;
You will now have to implement this method yourself though like
- (BOOL)isPersonForObject
{
return self.personForObject;
}
Note this only need be done if you choice to ignore convention which I wouldn't recommend.
Any questions just ask.
The code number two is equivalent to the Java version.
A #property in the most complete version defines the getter, setter and instance variable. You can also modify the declaration to specify only a getter, only a setter or to specify a different instance variable.
#property is shorthand for defining an instance variable and its corresponding accessors.
If you just define instance variables in the interface, you will not get the accessor methods.
See whenever you declare members in objective-C you should provide getters and setters for those members(Variables). But Objective-C supports something called synthesized accessors using the directives #property and #synthesize.
Now lets see program with synthesized accessors :
#import<Foundation/Foundation.h>
#interface Person : NSObject{
NSString * firstName;// declaring that Person class as variable firstName
NSString * lastName;// // declaring that Person class as variable lastName
}
#property NSString *firstName; // says to compiler that we want to define synthesized accesor for the firstName
#property NSString *lastName;// says to compiler that we want to define synthesized accesor for the lastName
#end
#implementation Person
#synthesize firstName, lastName;// synthesized accessor to be defined for firstName and lastName
#end;
int main(){
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc]init];
Person * p = [[Person alloc]init] ;
[p setFirstName:#"Yogish"]; // method setFirstName is implicitly defined by compiler
[p setLastName:#"Gowda"];// method setLastName is implicitly defined by compiler
NSLog(#"%#",p.firstName);
NSLog(#"%#",p.lastName);
[pool drain];
return 0;
}
Now coming back if u haven't used the #property and #synthesize you should have to write your own setters and getters method to set and get the members firstName and lastName. Since you're using #property and #synthesize the compiler will write getters and setter methods .
Hope this helps :)

What is the difference between the areas where you can declare instance variables in Objective-C? [duplicate]

Ever since starting to work on iOS apps and objective C I've been really puzzled by the different locations where one could be declaring and defining variables. On one hand we have the traditional C approach, on the other we have the new ObjectiveC directives that add OO on top of that. Could you folks helps me understand the best practice and situations where I'd want to use these locations for my variables and perhaps correct my present understanding?
Here's a sample class (.h and .m):
#import <Foundation/Foundation.h>
// 1) What do I declare here?
#interface SampleClass : NSObject
{
// 2) ivar declarations
// Pretty much never used?
}
// 3) class-specific method / property declarations
#end
and
#import "SampleClass.h"
// 4) what goes here?
#interface SampleClass()
// 5) private interface, can define private methods and properties here
#end
#implementation SampleClass
{
// 6) define ivars
}
// 7) define methods and synthesize properties from both public and private
// interfaces
#end
My understanding of 1 and 4 is that those are C-style file-based declarations and definitions that have no understanding whatsoever of the concept of class, and thus have to be used exactly how they would be used in C. I've seen them used for implementing static variable-based singletons before. Are there other convenient uses I'm missing?
My take from working with iOS is that ivars have been alost completely phased out outside of the #synthesize directive and thus can be mostly ignored. Is that the case?
Regarding 5: why would I ever want to declare methods in private interfaces? My private class methods seem to compile just fine without a declaration in the interface. Is it mostly for readability?
Thanks a bunch, folks!
I can understand your confusion. Especially since recent updates to Xcode and the new LLVM compiler changed the way ivars and properties can be declared.
Before "modern" Objective-C (in "old" Obj-C 2.0) you didn't have a lot of choices. Instance variables used to be declared in the header between the curly brackets { }:
// MyClass.h
#interface MyClass : NSObject {
int myVar;
}
#end
You were able to access these variables only in your implementation, but not from other classes. To do that, you had to declare accessor methods, that look something like this:
// MyClass.h
#interface MyClass : NSObject {
int myVar;
}
- (int)myVar;
- (void)setMyVar:(int)newVar;
#end
// MyClass.m
#implementation MyClass
- (int)myVar {
return myVar;
}
- (void)setMyVar:(int)newVar {
if (newVar != myVar) {
myVar = newVar;
}
}
#end
This way you were able to get and set this instance variable from other classes too, using the usual square bracket syntax to send messages (call methods):
// OtherClass.m
int v = [myClass myVar]; // assuming myClass is an object of type MyClass.
[myClass setMyVar:v+1];
Because manually declaring and implementing every accessor method was quite annoying, #property and #synthesize were introduced to automatically generate the accessor methods:
// MyClass.h
#interface MyClass : NSObject {
int myVar;
}
#property (nonatomic) int myVar;
#end
// MyClass.m
#implementation MyClass
#synthesize myVar;
#end
The result is much clearer and shorter code. The accessor methods will be implemented for you and you can still use the bracket syntax as before. But in addition, you can also use the dot syntax to access properties:
// OtherClass.m
int v = myClass.myVar; // assuming myClass is an object of type MyClass.
myClass.myVar = v+1;
Since Xcode 4.4 you don't have to declare an instance variable yourself anymore and you can skip #synthesize too. If you don't declare an ivar, the compiler will add it for you and it will also generate the accessor methods without you having to use #synthesize.
The default name for the automatically generated ivar is the name or your property starting with an underscore. You can change the generated ivar's name by using #synthesize myVar = iVarName;
// MyClass.h
#interface MyClass : NSObject
#property (nonatomic) int myVar;
#end
// MyClass.m
#implementation MyClass
#end
This will work exactly as the code above. For compatibility reasons you can still declare ivars in the header. But because the only reason why you would want to do that (and not declare a property) is to create a private variable, you can now do that in the implementation file as well and this is the preferred way.
An #interface block in the implementation file is actually an Extension and can be used to forward declare methods (not needed anymore) and to (re)declare properties. You could for instance declare a readonly property in your header.
#property (nonatomic, readonly) myReadOnlyVar;
and redeclare it in your implementation file as readwrite to be able to set it using the property syntax and not only via direct access to the ivar.
As for declaring variables completely outside of any #interface or #implementation block, yes those are plain C variables and work exactly the same.
First, read #DrummerB's answer. It a good overview of the whys and what you should generally do. With that in mind, to your specific questions:
#import <Foundation/Foundation.h>
// 1) What do I declare here?
No actual variable definitions go here (it's technically legal to do so if you know exactly what you're doing, but never do this). You may define several other kinds of things:
typdefs
enums
externs
Externs look like variable declarations, but they're just a promise to actually declare it somewhere else. In ObjC, they should only be used to declare constants, and generally only string constants. For instance:
extern NSString * const MYSomethingHappenedNotification;
You would then in your .m file declare the actual constant:
NSString * const MYSomethingHappenedNotification = #"MYSomethingHappenedNotification";
#interface SampleClass : NSObject
{
// 2) ivar declarations
// Pretty much never used?
}
As noted by DrummerB, this is legacy. Don't put anything here.
// 3) class-specific method / property declarations
#end
Yep.
#import "SampleClass.h"
// 4) what goes here?
External constants, as described above. Also file static variables can go here. These are the equivalent of class variables in other languages.
#interface SampleClass()
// 5) private interface, can define private methods and properties here
#end
Yep
#implementation SampleClass
{
// 6) define ivars
}
But very rarely. Almost always you should allow clang (Xcode) to create the variables for you. The exceptions are usually around non-ObjC ivars (like Core Foundation objects, and especially C++ objects if this is an ObjC++ class), or ivars that have weird storage semantics (like ivars that don't match with a property for some reason).
// 7) define methods and synthesize properties from both public and private
// interfaces
Generally you shouldn't #synthesize anymore. Clang (Xcode) will do it for you, and you should let it.
Over the last few years, things have gotten dramatically simpler. The side-effect is that there are now three different eras (Fragile ABI, Non-fragile ABI, Non-fragile ABI + auto-syntheisze). So when you see the older code, it can be a little confusing. Thus confusion arising from simplicity :D
I'm also pretty new, so hopefully I don't screw anything up.
1 & 4: C-style global variables: they have file wide scope. The difference between the two is that, since they're file wide, the first will be available to anyone importing the header while the second is not.
2: instance variables. Most instance variables are synthesized and retrieved/set through accessors using properties because it makes memory management nice and simple, as well as gives you easy-to-understand dot notation.
6: Implementation ivars are somewhat new. It's a good place to put private ivars, since you want to only expose what's needed in the public header, but subclasses don't inherit them AFAIK.
3 & 7: Public method and property declarations, then implementations.
5: Private interface. I always use private interfaces whenever I can to keep things clean and create a kind of black box effect. If they don't need to know about it, put it there. I also do it for readability, don't know if there are any other reasons.
This is an example of all kinds of variables declared in Objective-C. The variable name indicate its access.
File: Animal.h
#interface Animal : NSObject
{
NSObject *iProtected;
#package
NSObject *iPackage;
#private
NSObject *iPrivate;
#protected
NSObject *iProtected2; // default access. Only visible to subclasses.
#public
NSObject *iPublic;
}
#property (nonatomic,strong) NSObject *iPublic2;
#end
File: Animal.m
#import "Animal.h"
// Same behaviour for categories (x) than for class extensions ().
#interface Animal(){
#public
NSString *iNotVisible;
}
#property (nonatomic,strong) NSObject *iNotVisible2;
#end
#implementation Animal {
#public
NSString *iNotVisible3;
}
-(id) init {
self = [super init];
if (self){
iProtected = #"iProtected";
iPackage = #"iPackage";
iPrivate = #"iPrivate";
iProtected2 = #"iProtected2";
iPublic = #"iPublic";
_iPublic2 = #"iPublic2";
iNotVisible = #"iNotVisible";
_iNotVisible2 = #"iNotVisible2";
iNotVisible3 = #"iNotVisible3";
}
return self;
}
#end
Note that the iNotVisible variables are not visible from any other class. This is a visibility issue, so declaring them with #property or #public doesn't change it.
Inside a constructor it's good practice to access variables declared with #property using underscore instead self to avoid side effects.
Let's try to access the variables.
File: Cow.h
#import "Animal.h"
#interface Cow : Animal
#end
File: Cow.m
#import "Cow.h"
#include <objc/runtime.h>
#implementation Cow
-(id)init {
self=[super init];
if (self){
iProtected = #"iProtected";
iPackage = #"iPackage";
//iPrivate = #"iPrivate"; // compiler error: variable is private
iProtected2 = #"iProtected2";
iPublic = #"iPublic";
self.iPublic2 = #"iPublic2"; // using self because the backing ivar is private
//iNotVisible = #"iNotVisible"; // compiler error: undeclared identifier
//_iNotVisible2 = #"iNotVisible2"; // compiler error: undeclared identifier
//iNotVisible3 = #"iNotVisible3"; // compiler error: undeclared identifier
}
return self;
}
#end
We can still access the not visible variables using the runtime.
File: Cow.m (part 2)
#implementation Cow(blindAcess)
- (void) setIvar:(NSString*)name value:(id)value {
Ivar ivar = class_getInstanceVariable([self class], [name UTF8String]);
object_setIvar(self, ivar, value);
}
- (id) getIvar:(NSString*)name {
Ivar ivar = class_getInstanceVariable([self class], [name UTF8String]);
id thing = object_getIvar(self, ivar);
return thing;
}
-(void) blindAccess {
[self setIvar:#"iNotVisible" value:#"iMadeVisible"];
[self setIvar:#"_iNotVisible2" value:#"iMadeVisible2"];
[self setIvar:#"iNotVisible3" value:#"iMadeVisible3"];
NSLog(#"\n%# \n%# \n%#",
[self getIvar:#"iNotVisible"],
[self getIvar:#"_iNotVisible2"],
[self getIvar:#"iNotVisible3"]);
}
#end
Let's try to access the not visible variables.
File: main.m
#import "Cow.h"
#import <Foundation/Foundation.h>
int main(int argc, char *argv[]) {
#autoreleasepool {
Cow *cow = [Cow new];
[cow performSelector:#selector(blindAccess)];
}
}
This prints
iMadeVisible
iMadeVisible2
iMadeVisible3
Note that I was able to access the backing ivar _iNotVisible2 which is private to the subclass. In Objective-C all variables can be read or set, even those that are marked #private, no exceptions.
I didn't include associated objects or C variables as they are different birds. As for C variables, any variable defined outside #interface X{} or #implementation X{} is a C variable with file scope and static storage.
I didn't discuss memory management attributes, or readonly/readwrite, getter/setter attributes.

Objective-C instance variables?

I'm sure my confusion here is just a result of being stuck in a "Java mindset" and not understanding how Obj-C differs in this case.
In Java, I can declare a variable in a class, like this, and each instance of that class will have it's own:
MyClass {
String myVar;
MyClass() {
// constructor
}
}
In Obj-C I tried to do the same thing by declaring a variable only in the .m file like this:
#import "MyClass.h"
#implementation MyClass
NSString *testVar;
#end
My expectation here was that this variable has a scope limited to this class. So I created a second class (identical):
#import "MySecondClass.h"
#implementation MySecondClass
NSString *testVar;
#end
What I'm seeing (and has me baffled) is that changing the variable in one class, affects the value seen in the other class. In fact, if I set a breakpoint, and then "Jump to Definition" of the variable, it takes me to th
I've created an extremely small Xcode project that demonstrates the problem here.
Change this:
#implementation MyClass
NSString *testVar;
#end
to:
#implementation MyClass {
NSString *testVar;
}
// methods go here
#end
and you'll get what you expected.
As you had it, you are actually creating a global variable. The two global variables were combined into one by the linker which is why both changed when you set one. The variable in curly braces will be a proper (and private) instance variable.
Edit: After being downvoted for no apparent reason, I thought I'd point out the "old" way of doing things, and the new way.
The old way:
SomeClass.h
#interface SomeClass : UIViewController <UITextFieldDelegate> {
UITextField *_textField;
BOOL _someBool;
}
#property (nonatomic, assign) BOOL someBool;
// a few method declarations
#end
SomeClass.m
#implementation SomeClass
#synthesize someBool = _someBool;
// the method implementations
#end
Now the new and improved way with the modern Objective-C compiler:
SomeClass.h
#interface SomeClass : UIViewController
#property (nonatomic, assign) BOOL someBool;
// a few method declarations
#end
SomeClass.m
#interface SomeClass () <UITextFieldDelegate>
#end
#implementation SomeClass {
UITextField *_textField;
}
// the method implementations
#end
The new way has several advantages. The primary advantage is that none of the implementation specific details about the class appear in the .h file. A client has no need to know what delegates the implementation needs. The client has no need to know what ivars I use. Now, if the implementation needs a new ivar or it needs to use a new protocol, the .h file doesn't change. This mean less code gets recompiled. It cleaner and much more efficient. It also makes for easier editing. When I'm editing the .m file and realize I need a new ivar, make the change in the same .m file I'm already editing. No need to swap back and forth.
Also note the implementation no longer needs an ivar or #synthesize for the property.
What you probably want (unless you're using a very old OS and compiler) is to just use property syntax. I.e.:
#interface MyClass : NSObject
// method declarations here ...
#property (copy) NSString* myVar;
// ... or here.
#end
This will do what you intended to do. This will implicitly synthesize an instance variable and a getter/setter pair for this variable. If you manually wanted to create the instance variable (you generally don't need that unless you need your code to work on very old MacOS versions), this is what the above code does under the hood to create the ivar:
#interface MyClass : NSObject
{
NSString* _myVar;
}
// method declarations here.
#end
Note the curly braces, which tell the compiler that this is not just a global variable somewhere in between the methods, but actually an instance variable that belongs to this object.
If you are creating the property only for internal use and don't want clients of your class to mess with it, you can hide this away a little bit in everything but the oldest ObjC compilers by using a class extension which "continues" the class declaration from the header, but can be placed separate from it (so usually in your implementation file). A class extension looks like a category without a name:
#interface MyClass ()
#property (copy) NSString* myVar;
#end
And you can either put your property declaration in there, or even ivar declarations (again wrapped in curly brackets). You can even declare the same property as readonly in the class interface, and then re-declare it identical, but as readwrite in the extension, so that clients only read it, but your code can change it.
Note that, if you didn't use ARC (that is, you've switched off the default of Automatic Reference Counting), you would have to set all your properties to nil in your dealloc method (unless they're set to weak or assign of course).
NB - All the above are #interface sections. Your actual code will go in separate #implementation sections. This is so you can have header files (.h) you can hand off to your class's clients that just contain the portions you intend them to use, and hide away implementation details in the implementation file (.m) where you can change them without having to worry someone might have accidentally used them and you'll break other code.
PS - Note that NSStrings and other objects that you want the immutable flavor of, but that also exist in a mutable flavor (i.e. NSMutableString) should always be copy properties, because that will turn an NSMutableString into an NSString so that nobody on the outside can change the mutable string underneath you. For all other object types, you generally use strong (or retain if not ARC). For your class's owner (e.g. its delegate) you usually use weak (or assign if not ARC).
In Java
MyClass {
String myVar;
MyClass() {
// constructor
}
}
In Objective-c
MyClass.h
#interface MyClass : NSObject{
NSString* str; // Declaration
}
#end
MyClass.m
#implementation MyClass
-(void)initializieTheString
{
//Defination
}
#end
In objective-c, you define the variable as private by doing like so
MyClass.h
#interface MyClass : NSObject{
NSString* _myTestVar; // Declaration
}
#end
and refer to it in the implementation class by doing like so
MyClass.m
#import "MyClass.h";
#implementation MyClass
-(void)initializieTheString
{
_myTestVar= #"foo"; //Initialization
}
#end

Are curly braces required in #interface declarations in Objective-c?

The following code compiles:
#interface MyClass : ParentClass // missing {
// missing }
#property (nonatomic, copy) NSString *myString;
#end
I'm wondering if the curly braces in #interface declarations are actually necessary.
No, the { } section isn’t necessary; your code will compile fine without it. It’s the area where you declare instance variables, and if you’re not doing that, you’re free to leave it out. You don’t even actually need to declare ivars for your properties—the compiler’s smart enough to add them where they’re needed.
The compiler is clever enough to add your #property delarations to the class.
The only use for those brackets is when you want to make a variable private, protected or specifically public.
Example:
#interface Example: NSObject {
#public
int publicVar;
#private
int privateVar;
int privateVar2;
#protected
int protectedVar;
}
#end

Should I always use accessors for instance variables in Objective-C?

If I have a class with some IBOutlets, it seems kind of silly to create accessors for these.
But then I feel like I'm breaking OO practices by not always going through the accessors for instance variables.
I also feel the same way about some instance variables that should not be public, I'd rather not expose the inner workings of some classes. I can make the actual ivars private but the #property shorthand doesn't seem to be able to specify visibility. This leads me to not create accessors and just access the ivars directly. I'm not sure if this is frowned upon though. Is it?
What's the community's thoughts on this admittedly newbie question? (Please ignore dot syntax)
I'm not sure about accessing instance variables directly, I think one shouldn't, but for some variables it just doesn't make sense to use accessors. Like for the IBOutlets you mentioned.
I can only help you out with private accessors. Starting with Objective-C 2.0 you can declare extensions.
Class extensions are like “anonymous”
categories, except that the methods
they declare must be implemented in
the main #implementation block for the
corresponding class.
Just put this extension into a separate header file and you'll have private accessors that aren't visible in the header.
Public/Private
You can declare your iVars as in the #interface file to be readonly, but then re-declare them in a category so that your class can change them. Here's a quick intro to Categories.
An example:
//MyClass.h
#interface MyClass : NSObject {
NSString *name;
}
#property (readonly) NSString *name;
#end
And in the implementation file you can redeclare this:
//MyClass.m
#interface MyClass () //declare the class extension
#property (readwrite, copy) NSString *name; //redeclare the property
#end
#implementation MyClass
#synthesize name;
#end
Now, the name property is readonly external to the class, but can be changed by the class through property syntax or setter/getter syntax.
Really private iVars
If you want to keep iVars really private and only access them directly without going through #property syntax you can declare them with the #private keyword. But then you say "Ah, but they can always get the value outside the class using KVC methods such as setValueForKey:" In which case take a look at the NSKeyValueCoding protocol class method + (BOOL)accessInstanceVariablesDirectly which stops this.
IBOutlets as properties
The recommended way is to use #property and #synthesize. For Mac OS X, you can just declare them as readonly properties. For example:
//MyClass.h
#interface MyClass : NSObject {
NSView *myView;
}
#property (readonly) IBOutlet NSView *myView;
#end
//MyClass.m
#implementation MyClass
#synthesize myView;
#end