Reputation: 1349
I am trying to use fast enumeration to print all songs that are in a playlist, but it seems like I am doing it wrong. Could someone help me out? I have defined a Song class like this :
@interface Song : NSObject
@property (nonatomic,strong) NSString *title;
@property (nonatomic,strong) NSString *artist;
@property (nonatomic,strong) NSString *album;
@property (nonatomic,strong) NSString *playtime;
-(void) displaySong;
@end
displaySong function looks like this :
-(void) displaySong {
NSLog(@"%@ - %@ [%@] - %@\n", artist, title, album, playtime);
}
and now, to the PlayList class :
@interface PlayList : NSObject{
NSString *name;
NSMutableArray *playlist;
}
-(void) addSongToPlaylist: (Song *) song;
-(void) displayPlaylist;
@end
@implementation PlayList
-(void) addSongToPlaylist: (Song *) nameOfSong{
[playlist addObject:nameOfSong];
}
-(void) displayPlaylist{
NSLog(@"Playlist called %@:\n", name);
for(id obj in playlist)
{
if([obj isKindOfClass:[Song class]])
[obj displaySong];
}
}
// I also tried the displayPlaylist method this way, but it wasn't working either
-(void) displayPlaylist{
NSLog(@"Playlist called %@:\n", name);
for(Song *song in playlist)
{
[song displaySong];
}
@end
Could somebody please explain to me why my code isn't working?
And what displayPlaylist method is better?
Upvotes: 0
Views: 353
Reputation: 12770
You don't appear to be initializing your playlist array. You can do so lazily in your methods by checking for nil or by overriding the init method for your PlayList class.
Upvotes: 1
Reputation: 52227
You are never creating playlist
in the Playlist class' init add a playlist = [[NSMutableArray alloc] init] ;
And consider using a property for playlist (man — the similar names are quite annoying!)
If you don't want to have a init, you also can do:
-(void) addSongToPlaylist: (Song *) nameOfSong{
if(!playlist)
playlist= [[NSMutableArray alloc] init];
[playlist addObject:nameOfSong];
}
to answer the second question: it depends
if you know, that there are only instances of Song in the array, the second version is better, as a bit faster
if you don't know, it is the first, as otherwise a object would receive a message, it can't handle -> crash
or you can do
for(id obj in playlist)
{
if([obj respondsToSelector:@selector(displaySong)])
[obj displaySong];
}
if you wants to be sure, that the message is understood, no matter what object it is.
Upvotes: 3