1

Newbie Questions,

I have 3 Class , 3 of them are subclass of NSObject

a. Collection Class

This class will have 2 property

  1. masterSongs (Contains all songs) declared as NSMUtableSet (copy, nonatomic)
  2. listofPlaylists (contains all playlists) declared as NSMutableArray (copy, nonatomic)

b. Playlist Class

This Class will have 2 property

  1. playListName declared as NSString
  2. songLists declared as NSMutableArray (strong, nonatomic), only store reference to the song not copy of song.

c. Songs Class

This Class has 4 property declared as NSString :

  1. title
  2. artist
  3. playingtime
  4. album

Questions :

  1. I want to create removeSong method for Collection class, so when I delete particular song from Collection (masterSongs), it will also delete song in all of playList stored in Collection.listofPlaylists. but I am stuck with syntaxes*.

*I am using lookup method to create a NSSet and then using that set to remove song object from NSMutableSet masterSongs using - minusSet: method

also, I found that it's dangerous to change modify NSMutableSet while enumerating on it.

here I tried so far :

- (NSSet *) lookUpTitle: (NSString *)aName {

NSPredicate *filter = [NSPredicate predicateWithFormat:@"title == %@",aName];

NSSet *result = [self.masterSongs filteredSetUsingPredicate:filter];

if ([result count] == 0) {
    NSLog(@"not found");

    return nil;
}


else{
    return result;
}

}

- (void) removeSong: (NSString *)zSong{


    for (Song *aSong in masterSongs) {



        if ([self lookUpTitle:zSong] != nil) {

            NSMutableSet *container = [NSMutableSet setWithSet:self.masterSongs];
        }

    }

}



 - (void) addSong :(Song *)aSong{
    if (![masterSongs containsObject:aSong]) {

        [masterSongs addObject:aSong];

    } }

-(void) addPlaylist: (Playlist *)aPlayList{

    if ([listOfPlaylists containsObject:aPlayList]==YES) {

    }
    else
        [listOfPlaylists addObject:aPlayList];


}

-(void) removePlaylist: (Playlist *)aPlayList{
    if ([listOfPlaylists containsObject:aPlayList]) {

        [listOfPlaylists removeObjectIdenticalTo:aPlayList];
    }

    else{
        ;
    }

}
  • Just to emphasize it, though you did mention it, you ***cannot*** mutate a collection (set, array, dictionary) while enumerating over it. It can (should and maybe will) throw an exception if you do so. – Isaac Feb 22 '14 at 16:14

1 Answers1

0

-lookUpTitle: does most of the work for you. It returns a set of songs which need to be removed. You use -minusSet: to remove them from a NSMutableSet. To remove the songs from the playlists, you need to loop through your playlists and remove the songs in the set. You use -removeObjectsInArray: to remove them from a NSMutableArray.

- (void)removeSong:(NSString *)zSong
{
    NSSet *targets = [self lookUpTitle:zSong];

    if ([targets count] > 0) {
        [self.masterSongs minusSet:targets];

        for (Playlist *playlist in self.listOfPlaylists) {
            // -allObjects converts the set into an array.
            [playlist.songLists removeObjectsInArray:[targets allObjects]];
        }
    }
}

You asked a new question about properties.

@property (copy) NSMutableSet *masterSongs;

Is a bad idea. A -setMasterSongs: method is automatically generated which will look something like this:

- (void)setMasterSongs:(NSMutableSet *)masterSongs
{
    if (_masterSongs != masterSongs) {
        _masterSongs = [masterSongs copy];
    }
}

The problem is -[NSMutableSet copy] returns an NSSet; similarly, -[NSMutableArray copy] returns NSArray. This is why you ran into a problem. NSSet and NSArray are immutable, so they don't contain any methods which will change their contents.

Jeffery Thomas
  • 42,202
  • 8
  • 92
  • 117
  • Sorry for my late reply, was offline yesterday. I have questions regarding with property declaration. I declared: NSMutableSet and NSMutableArray as Copy, Nonatomic on Collection Class and I also declared NSMutableArray as strong, nonatomic on Playlist Class, this condition, when I run Collection instance method addSong:(Song *)aSong or method addPlaylist:(Playlist *)aList both method throw unrecognized selector exception. but when I changed Collection Class property both NSMutableArray and NSMutableSet to strong, nonatomic, it run properly. so, Copy can't contain references or what? – user3213703 Feb 22 '14 at 08:16
  • some information about my last question is in here http://stackoverflow.com/questions/3220120/nsmutablearray-addobject-nsarrayi-addobject-unrecognized-selector-sent-t but I still don't get it, why copy throw exception in addSong method, although Collection Class masterSongs declared as copy, nonatomic and Song property also declared as copy – user3213703 Feb 22 '14 at 08:51
  • @user3213703 these are new questions. You really should post them as a new question instead of tacking them onto an unrelated question. – Jeffery Thomas Feb 22 '14 at 15:31
  • @user3213703 I updated my answer with a short answer to you new question. – Jeffery Thomas Feb 22 '14 at 15:44
  • thanks for both of your answer & advice, I'll keep it in mind. – user3213703 Feb 22 '14 at 16:17
  • regarding to NSPredicate query like my code above, it didn't work properly when I tried to run it. from my previous exercise my NSPredicate worked, but while I am trying to apply it on this case, it didn't work out, strange. if you don't mind, could you please look at it? http://stackoverflow.com/questions/21962546/how-to-use-nspredicate-to-filter-nsmutableset-which-contains-composite-object-fr – user3213703 Feb 23 '14 at 06:32