新手问题,
我有 3 个类,其中 3 个是 NSOBject 的子类。
收藏类,有 2 个属性,masterSong 作为 NSMutableSet(强,非原子)和listOfPlaylists 作为 NSMutableArray(强,非原子)
播放列表类
拥有2个属性,播放列表名称为 NSString(复制,非原子)和歌曲列表为 NSMutableArray(强,非原子)
3 . 歌曲班
有 4 个属性:标题、艺术家、专辑、播放时间为 NSString(复制、非原子)。
masterSong 将包含 Song 对象,listOfPlaylist 将包含 Playlist 对象。
而songList只存储对Song对象的引用。
我想通过在 masterSong 中查找歌曲的标题、艺术家或专辑来为 Collection 类创建removeSong 方法。
如果查找找到1,它将返回NSSet,返回的NSSet将作为minusSet:方法中的参数,从masterSong和所有Playlist.songList中删除歌曲。
但是,我不知道如何写下 NSPredicate 语法来从包含歌曲对象的 masterSong 中过滤掉 .title 或 .album 或 .artist 。
这是我到目前为止所得到的
收藏.m
- (void) removeSong: (NSString *)zSong{
//remove from reference playlist
NSSet *targets = [self lookUpTitle:zSong];
if ([targets count]>0) {
[self.masterSongs minusSet:targets];
for (Playlist *playlist in listOfPlaylists) {
// -all objects converts the set into array.
[playlist.songList removeObjectsInArray:[targets allObjects]];
}
}
else
;
}
Xcode 在执行 LookUpTitle 方法时抛出异常,表示由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“无法查找值(标题:无返回点,艺术家:Cafe Bleu,专辑:CBSB,播放时间:3 :56) 字符串(你知道什么);值不是字符串
- (NSSet *) lookUpTitle: (NSString *)aName {
NSString *filters = @"%K CONTAINS [cd] %@";
NSPredicate *filter = [NSPredicate predicateWithFormat:filters, @"title", aName];
NSSet *result = [masterSongs filteredSetUsingPredicate:filter];
if ([result count] == 0) {
NSLog(@"not found");
return nil;
}
else{
return result;
}
}
我知道主要问题在于lookUpTitle方法
NSPredicate *filter = [NSPredicate predicateWithFormat:filters, @"title", aName];
NSSet *result = [masterSongs filteredSetUsingPredicate:filter];
过滤器以错误的方式进行过滤,虽然它应该过滤 NSString 对象(标题、艺术家或专辑),但 masterSong 包含歌曲对象,如何使用 NSPredicate 访问放置在 masterSong 内的歌曲对象中的标题、艺术家、专辑?
对于这种情况还有其他有效的方法吗?
谓词编程指南 https://developer.apple.com/library/mac/documentation/cocoa/conceptual/predicates/Articles/pUsing.html#//apple_ref/doc/uid/TP40001794-CJBDBHCB仅显示包含字符串的示例集/数组
我找到了其他线程有类似的主题 https://stackoverflow.com/questions/9558335/filter-an-nsarray-which-contains-custom-objects,但是 block 读起来很混乱,并且在我的情况下仍然不起作用。
Edit :根据响应者 #1 的请求添加部分代码(Class.m 方法)。
这是 .m 文件中与我的问题相关的一些方法
Main.m
#import <Foundation/Foundation.h>
#import "MusicCollection.h"
#import "Playlist.h"
#import "Song.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
// insert code here...
// NSLog(@"Hello, World!");
//create Songs
Song *aSong = [[Song alloc]initWithTitle:@"Whole point of no return" withArtist:@"Cafe Bleu" withAlbum:@"CBSB" withPlaytime:@"3:56"];
Song *bSong = [[Song alloc]initWithTitle:@"Council Meetin'" withArtist:@"Cafe Bleu" withAlbum:@"CBSB" withPlaytime:@"4:00"];
Song *cSong = [[Song alloc]initWithTitle:@"Hayate" withArtist:@"Spitz" withAlbum:@"Indigo Chiheisen" withPlaytime:@"4:21"];
Song *dSong = [[Song alloc]initWithTitle:@"I have a Dreams" withArtist:@"WestLife" withAlbum:@"Season" withPlaytime:@"4:11"];
Song *eSong = [[Song alloc]initWithTitle:@"What Do You Know" withArtist:@"David Choi" withAlbum:@"Tomorrow" withPlaytime:@"3:46"];
//create playList
Playlist *playlistA = [[Playlist alloc]initWithName:@"Playlist A"];
Playlist *playListB = [[Playlist alloc]initWithName:@"Playlist B"];
//store Song A & B to Playlist A and Song A,B,C to playlist B
[playlistA addSong:aSong];
[playlistA addSong:bSong];
[playListB addSong:aSong];
[playListB addSong:bSong];
[playListB addSong:cSong];
// [playListB removeSong:eSong];
//Creating Master Collection
MusicCollection *myCollection = [[MusicCollection alloc]initWithName:@"Library"];
[myCollection addPlaylist:playlistA];
[myCollection addPlaylist:playListB];
[myCollection addSong:eSong];
[myCollection addSong:dSong];
[myCollection removePlaylist:playListB];
[myCollection removeSong:aSong];
NSSet *container2 = [myCollection lookUpTitle:@"What"];
NSLog(@"%@",container2);
// NSLog(@"%@",myCollection);
}
return 0;
}
收藏.m
-(instancetype) initWithName: (NSString *)aName{
self = [super init];
if (self) {
self.name = [NSMutableString stringWithString:aName];
self.listOfPlaylists = [NSMutableArray array];
self.masterSongs = [NSMutableSet set];
}
return self;
}
-(instancetype) init{
return [self initWithName:@""];
}
-(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{
;
}
}
- (void) displaySong{
NSLog(@"displaying all song in Collection");
NSLog(@" %@",self.masterSongs);
}
- (void) addSong :(Song *)aSong{
if (![masterSongs containsObject:aSong]) {
[masterSongs addObject:aSong];
}
}
- (void) removeSong: (NSString *)zSong{
//remove from reference playlist
NSSet *targets = [self lookUpTitle:zSong];
if ([targets count]>0) {
[self.masterSongs minusSet:targets];
for (Playlist *playlist in listOfPlaylists) {
// -all objects converts the set into array.
[playlist.songList removeObjectsInArray:[targets allObjects]];
}
}
else
;
}
- (NSSet *) lookUpTitle: (NSString *)aName {
NSString *filters = @"%K CONTAINS [cd] %@";
NSPredicate *filter = [NSPredicate predicateWithFormat:filters, @"title", aName];
NSSet *result = [masterSongs filteredSetUsingPredicate:filter];
if ([result count] == 0) {
NSLog(@"not found");
return nil;
}
else{
return result;
}
}
播放列表.m
- (void) addSong :(Song *)aSong{
if (![songList containsObject:aSong]) {
[songList addObject:aSong];
}
}
- (void) removeSong: (Song *)aSong{
if ([songList containsObject:aSong]){
[self.songList removeObjectIdenticalTo:aSong];
}
}
- (instancetype) initWithName: (NSString *)aPLName{
self = [super init];
if (self) {
self.songList = [NSMutableArray array];
self.playlistName = aPLName;
}
return self;
}
- (instancetype)init{
return [self initWithName:@""];
}
Song.m
- (instancetype) initWithTitle: (NSString *)aTitle withArtist: (NSString *)anArtist withAlbum: (NSString *)aAlbum withPlaytime: (NSString *)playingTime{
self = [super init];
if (self) {
self.artist = [NSMutableString stringWithString:anArtist];
self.album = [NSMutableString stringWithString:aAlbum];
self.title = [NSMutableString stringWithString:aTitle];
self.playtime = [NSMutableString stringWithString:playingTime];
}
return self;
}
-(instancetype) init{
return [self initWithTitle:@"null" withArtist:@"null" withAlbum:@"null" withPlaytime:@"null"];
}