0

I am trying add a Song* object to a Mutable array and I am stumped as the count of the array is not increasing in spite of adding the object.

Song.h

#import <Foundation/Foundation.h>

@interface Song : NSObject

@property(copy, nonatomic) NSString *title, *album, *artist;
@property(copy, nonatomic) NSNumber *playTime;

@end

Song.m

#import "Song.h"

@implementation Song

@end

Playlist.h

#import <Foundation/Foundation.h>
@class Song;

@interface Playlist : NSObject

@property(copy, nonatomic) NSMutableArray *playListArray;

-(void) addSong: (Song *) tempSongToBeAdded;
-(void) removeSong: (Song *) tempSongToBeremoved;
-(void) listOfSongs;
-(NSUInteger) entries;

@end

Playlist.m

#import "Playlist.h"
#import "Song.h"

@implementation Playlist

-(void) addSong: (Song *) tempSongToBeAdded{
    NSLog(@"%s song is being added.", [tempSongToBeAdded.title UTF8String]);
    [self.playListArray addObject:tempSongToBeAdded];
}
-(void) removeSong: (Song *) tempSongToBeremoved{
    [self.playListArray removeObject:tempSongToBeremoved];
}

-(NSUInteger) entries{
    return [self.playListArray count];
}


    -(void) listOfSongs{
        NSLog(@"Hi");
        for (Song *tempSong in self.playListArray) {
            NSLog(@"title: %s", [tempSong.title UTF8String]);
        }
    }

@end

Main.m

#import <Foundation/Foundation.h>
#import "Song.h"
#import "Playlist.h"

int main(int argc, const char * argv[])
{

@autoreleasepool {

    Song *song1 = [[Song alloc] init];
    song1.title = @"Manasa";
    song1.album = @"Ye Maya Chesava";
    song1.artist = @"A. R. Rahman";
    song1.playTime = [NSNumber numberWithDouble:4.56];

    Playlist *playlist1 = [[Playlist alloc] init];

    [playlist1 addSong:song1];
    NSLog(@"The total number of songs are %lu",[playlist1 entries]);
    [playlist1 listOfSongs];




    }
return 0;
}

I am getting the entries in the playlist as 0 and and the list of songs as empty. I am not getting any compile errors and I have no idea why the objects are not getting added to the array.

4
  • An oddity of Objective-C is that if you call a method using a nil pointer for the "object", the call returns nil/zero, without any error indication. So you can "add" a dozen objects to your nil "array" and when you ask it will tell you that the count is still zero (since [nil count] always returns zero). Commented Mar 20, 2014 at 3:51
  • I am trying to init the array but when I am doing that I am getting a runtime error. Commented Mar 20, 2014 at 3:53
  • [[NSMutableArray] alloc] init] is giving you a runtime error?? Commented Mar 20, 2014 at 3:55
  • Yes. imgur.com/159Jzlg Commented Mar 20, 2014 at 3:58

1 Answer 1

1

Your variable playListArray is never initialized and is always nil. You need to initialize it using:

playListArray = [[NSMutableArray] alloc] init];

You can add an init method in your Playlist class where you initialize this object.

- (id)init
{
    self = [super init];
    if (self)
    {
        playListArray = [[NSMutableArray] alloc] init];
    }
    return self;
}

EDIT:
The problem seems to be how you declared the property

@property(copy, nonatomic) NSMutableArray *playListArray;

It is declared as copy, that means that even when you do playListArray = [[NSMutableArray] alloc] init], your variable playListArray gets a copy of the initialized array, but the copy protocol is inherited from NSArray, not from NSMutableArray, so you get an immutable array. You can check this in the NSMutableArray documentation. You need to change copy for retain (you're not using ARC, right?).

In fact I see that you're using copy for most of your properties, if there's no particular reason for this, I would change them to retain.

Sign up to request clarification or add additional context in comments.

4 Comments

I did that but I am getting a Runtime error in the addsong menthod. Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI addObject:]: unrecognized selector sent to instance 0x1001031a0
It seems like you're initializing the object as NSArray instead of NSMutableArray
Yes, copy is hardly ever used for properties that are object pointers. Should only be used in special cases.
@HotLicks, @Morpheus: copy should be used for immutable objects with mutable subclasses. Have a look at Encapsulating Data in Apple's "Programming with Objective-C" guide

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.