nemesis
nemesis

Reputation: 1349

Objective C fast enumeration trouble

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

Answers (2)

Jon Shier
Jon Shier

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

vikingosegundo
vikingosegundo

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

Related Questions