Question

This is my first time trying to create an object to store my data and am having some trouble. Im not sure im going about this the right way.

song.h:

#import <Foundation/Foundation.h>

@interface Song : NSObject{
    NSString *songID;
    NSString *title;
    NSString *artist;
    NSString *album;
    NSString *length;
    NSString *votes;
}
-(void)setSongID:(NSString*) p_songId;
-(void)settitle:(NSString*) p_title;
-(void)setartist:(NSString*)p_artist;
-(void)setalbum:(NSString*) p_album;
-(void)setlength:(NSString*) p_length;
-(void)setvotes:(NSString*) p_votes;

-(NSString*)getSongID;
-(NSString*)gettitle;
-(NSString*)getartist;
-(NSString*)getalbum;
-(NSString*)getlength;
-(NSString*)getvotes;

@end

song.m

#import "Song.h"

@implementation Song


-(void)setSongID:(NSString*) p_songId;{

}
-(void)settitle:(NSString*) p_title{

}

-(void)setartist:(NSString*)p_artist{

}
-(void)setalbum:(NSString*) p_album{

}
-(void)setlength:(NSString*) p_length{

}
-(void)setvotes:(NSString*) p_votes{

}

-(NSString*)getSongID{

}
-(NSString*)gettitle{

}
-(NSString*)getartist{

}
-(NSString*)getalbum{

}
-(NSString*)getlength{

}
-(NSString*)getvotes{

}

@end

My implementation file cannot see any of the variables, for example I cannot set the songID with self.songID = p_songID

Does objective-c have a built in way of dealing with these setters/getters, am I going about this the wrong way?

Was it helpful?

Solution

Objective C has a way of setting up getters and setters for you so that you don't have to worry about writing them yourself. It does this through properties. To set up a property, in your header file write

@property (strong, nonatomic) NSString *songID;

Typically, you will use the strong and nonatomic modifiers unless you have a reason not to. You can research other parameters if you're interested. After writing that line, the getters and setters are generated for you.

To use this property within the class, you simply use dot notation and the self object. For example, to set the value, you write

self.songID = @"66777888";

You access the value of the property in the same way. For example, to assign another string equal to the value, you write

NSString *other = self.songID; 

If you want to access these values outside of the subclass, you still use dot notation, except now using the instance of the class. For example, if you want to set the songID from another class, you can write

Song *song = [[Song alloc] init];
song.songID = @"790";

OTHER TIPS

Does objective-c have a built in way of dealing with these setters/getters, am I going about this the wrong way?

Yes, Objective-C has his own way : @property.

You just want to declare a property like that :

@interface Song : NSObject
@property (strong, nonatomic) NSString * songID;
@end;

This will generate, automatically :

- (void)setSongID:(NSString *)songID;
- (NSString *)songID;

So you don't have to write your own one.

By the way, strong means that you want to own the object, it's yours. And nonatomic is about thread safety.

You would simply write your class as

@interface Song : NSObject

@property (strong, nonatomic) NSString *songID;
@property (strong, nonatomic) NSString *title;
@property (strong, nonatomic) NSString *artist;
@property (strong, nonatomic) NSString *album;
@property (strong, nonatomic) NSString *length;
@property (strong, nonatomic) NSString *votes;

@end

Member variables and getters/setters are generated by the compiler. If you do not want a setter for a member then you would use readonly specifier:

@property (strong, nonatomic, readonly) songID;

You only need to provide an implementation of a getter or a setter manually if you need a special processing. Just an artificial example:

@implementation Song

void setTitle:(NSString*)title
{
    if (some conditions)
        self.votes = @"winner";

    self.title = title;
}

@end

Letting the compiler to generate getters and setters not only saves you boring typing and creates a more concise code but also takes care of synchronisation and reference counting issues. It doesn't apply in all cases though. These are the things one need to worry about if generating atomic properties and/or not using ARC.

It was noted here that compiler generates member variables for you by prefixing properties with underscores. E.g. _songID or _title, etc. Inside the class implementation you may access and set variables like

self.title = @"title";
_title = @"title";

Which one is appropriate? self.title - in most cases, _title - in some. Remember non ARC code and atomic implementation if applies.

If you want to make your property accessible from you class only (aka private member) then use class extension. In your implementation .m file:

@interface Song()
@property (strong, nonatomic) foo;
@end

@implementation Song
...
@end

And for completeness I'd add that you may make only getter or setter 'private'.

The naming convention for accessor methods is that getters have the same name as the property possibly, for boolean properties, prefixed with is. They should not be prefixed with get. And setters are named with the prefix set followed by the capitalized property name.

So, you might have:

- (NSString*) title;
- (void) setTitle:(NSString*)newTitle;

Etc.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top