PDA

View Full Version : Creating My First Class




teguh123
Mar 31, 2011, 01:49 PM
@interface Badger : NSObject {
NSString * Title;
NSString * BuildingAddress;
NSString * Street;
NSString * District;
NSString * City;
NSString * Country;
}
@property (retain) NSString * Title;
@property (retain) NSString * BuildingAddress;
@property (retain) NSString * Street;
@property (retain) NSString * District;
@property (retain) NSString * Country;
@end


@implementation Badger
@synthesize Title;
@synthesize BuildingAddress;
@synthesize Street;
@synthesize District;
@synthesize Country;
@end

I saw problem here'

Why do I need to have a separate .mm and .h file? Why not put the whole thing in the .h file?

Why do I need to write Title 3 times just to declare a property?

In vb.net I only need to write public property Title and that's it

Am I doing a good programming practice here? I am sure that the property on a class should be retain. I can't think of any scenario where it's not retain. The class "own" the property and the property should never be destroyed unless the class is destroyed.



admanimal
Mar 31, 2011, 02:20 PM
I saw problem here'

Why do I need to have a separate .mm and .h file? Why not put the whole thing in the .h file?


So you can import the header file (i.e. the interface declaration) into other classes that make use of your class without duplicating the implementation code.


Why do I need to write Title 3 times just to declare a property?


Because you're not just declaring it as a property.

The first Title declares an instance variable of Badger. The second Title declares a retained property. The third Title synthesizes the accessors.

Declaring the instance variable is optional if you are using the latest Obj-C compiler (I know it works in LLVM, pretty sure GCC works too) and you declare it as a property and synthesize the accessors. However, it is possible to have an instance variable that is not a property, or a property that is not backed by an instance variable, or a property that does not have synthesized accessors, which is why you generally need to specify all three if that is what you want.



Am I doing a good programming practice here? I am sure that the property on a class should be retain. I can't think of any scenario where it's not retain. The class "own" the property and the property should never be destroyed unless the class is destroyed.

First of all, your interface and implementation need to be in separate files for the reason I gave above. Your properties and instance variables (and everything except for class names) should begin with lower case letters.

Do you understand precisely what retain means? It does involve ownership, but that doesn't mean that you should specify retain for an int property, for example, or for a delegate. I recommend you carefully read up on the subject if you aren't sure about it.

huskerchad
Mar 31, 2011, 02:56 PM
Retain may be the most common policy, but it's certainly not the only one. In your example, it's probably the wrong one!

For NSString, one problem is that you could be getting a NSMutableString instance (it's a subclass). If you just retain a string that's provided to you, and then the caller changes the string (potentially to something completely unrelated to your purpose), you're now holding on to an "address" that may be "Hey did you see that new Brad Pitt movie" instead of "1234 Main Street". Copy is a more common policy with NSString's unless you have very tight control over who is providing you with strings.

teguh123
Mar 31, 2011, 09:27 PM
Retain may be the most common policy, but it's certainly not the only one. In your example, it's probably the wrong one!

For NSString, one problem is that you could be getting a NSMutableString instance (it's a subclass). If you just retain a string that's provided to you, and then the caller changes the string (potentially to something completely unrelated to your purpose), you're now holding on to an "address" that may be "Hey did you see that new Brad Pitt movie" instead of "1234 Main Street". Copy is a more common policy with NSString's unless you have very tight control over who is providing you with strings.

I wouldn't worry about NSMutableString and NSString. I think NSString can be "changed" by simply releasing the old one and replacing it with new string. I do not think the string will change once it's initialized anyway.

Anyway thanks for all the info.

I just think that declaring a variable name 3 times is just cumbersome for "default" behavior. I mean for non default behavior it makes perfect sense. Say somebody want to implement their own special getter or setters.

The next question is that district should be a collection or an array. One "Badger" can contain several districts. How would I go about this?

I will need samples of well written classes


@interface Badger : NSObject {
/*NSString * Title;
NSString * BuildingAddress;
NSString * Street;
NSString * District;
NSString * City;
NSString * Country;*/
}
@property (retain) NSString * Title;
@property (retain) NSString * BuildingAddress;
@property (retain) NSString * Street;
@property (retain) NSString * District;
@property (retain) NSString * Country;
@end


@implementation Badger
@synthesize Title;
@synthesize BuildingAddress;
@synthesize Street;
@synthesize District;
@synthesize Country;

- (void)dealloc {
self.Title=nil; //This one should call release by itself (boy 3 times mentioning one variable name for each property)
self.BuildingAddress=nil;
self.Street=nil;
self.District=nil;
self.Country=nil;
[super dealloc];
}


@end

admanimal
Mar 31, 2011, 10:28 PM
I wouldn't worry about NSMutableString and NSString. I think NSString can be "changed" by simply releasing the old one and replacing it with new string. I do not think the string will change once it's initialized anyway.


Releasing and replacing an NSString is not the same thing as changing a NSMutableString. I'm not going to explain the whole thing but you need to make sure you understand exactly why you usually want to declare NSString properties as copy rather than just retain.

RonC
Apr 1, 2011, 07:00 AM
I just think that declaring a variable name 3 times is just cumbersome for "default" behavior. I mean for non default behavior it makes perfect sense. Say somebody want to implement their own special getter or setters.


It is cumbersome. Unfortunately, that's how Obj-C works. It's not particularly different than other programming languages of it's era that are C derivatives (e.g., C++). More modern programming languages (C#, Java) have a single file containing the full interface and implementation, while yet other programming languages are completely dynamically message based (Smalltalk, Ruby, Python). Get over it - it's the price to play in the game.

You're making it worse than it is by not exactly demonstrating a complete understanding of WHAT you're trying to accomplish.

a) The member variable in the class definition defines a member variable. It doesn't have to have a property associated with it, it's just part of an object's data.

b) The property statement in the @interface section declares an EXTERNAL interface for getter/setter methods on a member variable (or with readonly, only a getter is created). One key thing you're missing is that you don't have to have a member variable with the same name declared separately. If you have a "property int bob;" and no bob member is in the class, one is created for you, for free.

c) The @synthesize statement in the @implementaton section creates 2 methods (again, 1 if readonly is used) to implement the getter and setter.

You don't need the @synthesize either, as long as you implement the getter and setter methods yourself. Using bob as the example, @synthesize bob; becomes the equivalent of:

-(int) bob
{
return bob;
}

-(void) setBob:(int)anInt
{
bob = anInt;
}


d) The final ones (in dealloc) are caused by your own use of retain as a property modifier. You chose to retain the instances, hence you created the problem so you should clean it up. Perhaps you don't have a very clear understanding of memory management in Obj-C?

If this confuses you, read the documentation. If you need to have someone explain it to you, then go into iTunes U and download the Stanford iPhone programming courses. They're very good.



The next question is that district should be a collection or an array. One "Badger" can contain several districts. How would I go about this?


I don't know. Answer these questions:
Does order matter?
Does the list of districts change over time?
Are all districts equivalent (i.e., instances of the same class)?


Surely you must already know the answer to these since it feels like you're porting an application. Read the Collections guide and pick one that matches your needs.


I will need samples of well written classes


They're available on the developer website, provided by Apple. Start reading the documentation, it will help.

People here are good about answering questions, but nobody here is going to write your code for you. If you don't understand HOW Obj-C works (which I don't think you do yet), you will struggle with everything iOS related - they are two sides of the same coin. Slow down, take some time to learn WHY you're writing that code instead of just copy/paste (as I said, the Stanford courses are very good) and come back with a question that demonstrates some understanding. When you run into a roadblock, we'll help you get past it.

Ron C