如何使用 NSPredicate 过滤包含其他类的复合对象的 NSMutableSet?

2024-03-03

新手问题,

我有 3 个类,其中 3 个是 NSOBject 的子类。

  1. 收藏类,有 2 个属性,masterSong 作为 NSMutableSet(强,非原子)和listOfPlaylists 作为 NSMutableArray(强,非原子)

  2. 播放列表类

拥有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"];
}

你已经超载了-removeSong:这让你感到困惑。在Playlist, -removeSong:需要一个Song实例,但是在Collection, -removeSong:需要一个NSString例如歌曲标题。

问题是你传递了一个实例Song到期望的版本NSString.

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

应该是

- (void)removeSong:(Song *)aSong
{
    NSSet *targets = [self lookUpTitle:aSong.title];
    // …
}

or

- (void)removeSongWithTitle:(NSString *)aTitle
{
    NSSet *targets = [self lookUpTitle:aTitle];
    // …
}

我更改了该方法的第二个版本的名称,以清楚地显示预期的参数是什么。当你想使用第二个版本时,你可以传递消息[myCollection removeSongWithTitle:aSong.title]

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 NSPredicate 过滤包含其他类的复合对象的 NSMutableSet? 的相关文章

  • 避免 UIImage 的 imageNamed - 内存管理

    我正在经历这个链接 http akosma com 2009 01 28 10 iphone memory management tips 我遇到了一个点避免 UIImage 的 imageNamed 出于什么原因我们应该避免这种情况 它会
  • 为沙盒 Cocoa 应用程序创建临时文件

    我的应用程序是沙箱化的 根据最新的应用程序商店指南 我想创建一些临时文件 我可以这样做吗 如果 是 我可以在哪里这样做 有没有预先指定的路径 还有访问该路径的命令 您应该使用NSTemporaryDirectory 函数 它将查找并返回适合
  • CBPeripheral 名称有时为 null

    我正在开发一个应用程序来与蓝牙 LE 外围设备进行通信 我目前正在测试的外围设备是其中之一these http www ti com tool cc2540dk mini 有趣的是 有时当我发现它时 我会得到它的正确名称 SimpleBLE
  • 如何减少典型 iPhone 应用程序的启动时间?

    需要明确的是 这是一个普通的 iPhone 应用程序 而不是游戏 我在网上读过几次 一些开发人员提到他们正在努力改进 减少应用程序的启动时间 但从来没有提供任何关于如何做到这一点的良好背景信息 那么问题很简单 如何减少 iPhone 应用程
  • 是什么导致了这个 iPhone 崩溃日志?

    我有点卡住了 需要解决这个问题 因为我的一个应用程序出现了随机崩溃 而这些崩溃并不总是能够重现 这是崩溃日志之一 Incident Identifier 59865612 9F00 44EA 9474 2BF607AD662E CrashR
  • 如何确定iPhone铃声的当前级别?

    我正在使用 AVSystemController 将 iPhone 铃声静音 但我不知道如何确定铃声的当前级别 有任何想法吗 PS 是的 我知道使用 AVSystemController 可能会导致应用程序被 App Store 禁止 这不
  • iOS中的performSelector有什么用

    的作用是什么执行选择器 比较 self btnClicked and self performSelector selector btnClicked void btnClicked NSLog Method Called 两者都对我来说工
  • 如何检测Retina高清显示屏?

    UIScreen有一个新的 nativeScaleiOS 8 中的属性 但文档没有提及它 property nonatomic readonly CGFloat nativeScale 还有一个scale属性 但文档说它是 2 用于视网膜显
  • 适用于 Objective-C / iPhone 的良好 HTTP 库? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 UPDATE 这个问题显然已经过时了 参见日期 我建议只使用现代 iOS7 功能 例如 NSURLSession 我想 这个问题是为了历史
  • 确定 NSView 是否绘制的正确方法

    有没有正确的方法来确定是否NSView实际上是否在当前视图层次结构中绘制 考虑以下情况 视图完全在屏幕外 不是强制性的 该视图不在视图层次结构的顶部 The isHidden and isHiddenOrHasHiddenAncestor不
  • 线程 1:信号 SIGABRT - AppDelegate.h

    main m Journey Created by Julian Buscema on 2014 07 13 Copyright c 2014 Julian Buscema All rights reserved import
  • iPhone 快照,包括键盘

    我正在寻找拍摄整个 iPhone 屏幕 包括键盘 的正确方法 我找到了一些截取屏幕的代码 CGRect screenCaptureRect UIScreen mainScreen bounds UIView viewWhereYouWant
  • PrepareForSegue之谜

    我在两个不同的 VC 中有一个prepareForSegue 方法 一个使用一个if声明 而另一个旨在使用switch 除了名称之外 代码几乎相同 这个效果很好 void prepareForSegue UIStoryboardSegue
  • 我什么时候应该对 IBOutlet 使用弱或强限定符? [复制]

    这个问题在这里已经有答案了 可能的重复 ARC 下 IBOutlets 应该强还是弱 https stackoverflow com questions 7678469 should iboutlets be strong or weak
  • 使用 Storyboard 时获取 NSManagedObjectContext

    目标是获取当前的 NSManagedObjectContext 以便使用 Core Data 在 iOS 4 3 中 我将 UINavigationController 的委托设置为 AppDelegate 如下所示 在 AppDelega
  • 在 UIWebView 中隐藏键盘

    有没有办法让 UIWebView 关闭所有关联的输入控件 例如键盘 选择器 还没有在带有选择器的网络视图中尝试过 但这绝对可以消除键盘 theWebView endEditing YES
  • 设置 TableView setEditing 时无法选择 UITableViewCell

    我希望能够选择多行 如下所示的默认邮件应用程序 我有一个名为编辑的按钮 可以调用 self myTableView setEditing YES animated YES 编辑按钮成功显示单元格左侧的圆圈 如上所示的邮件应用程序 但是 当我
  • Obj-C / Swift 项目中的致命陷阱异常

    我开始将 Swift 代码集成到我的 Obj C 项目中 一切都进展顺利 但今天 当我更新到 Xcode 6 1 时 事情变得很糟糕 我从之前运行良好的 Swift 代码中收到了许多 陷阱 异常 第一次崩溃位于我的 UIFont 扩展中 这
  • 删除 UINavigationBar 下的 1px 边框 - 不起作用

    IBOutlet var navBar UINavigationBar self navBar setBackgroundImage UIImage forBarMetrics UIBarMetrics Default self navBa
  • 观察 UIDatePicker 的变化

    我注意到没有委托来观察 UIDatePicker 中的变化 有没有一种方法可以在不确认任何内容的情况下检测选择器中何时进行更改 例如它旋转并落在新数字上的那一刻 我希望能够检测到这一点 我考虑过关键值观察 但我不认为有一个属性会立即改变 您

随机推荐

  • 为什么 jsx 中的三元运算符不起作用

    我有一个反应组件 在其中我想使用三元运算符显示一个子组件 这似乎不起作用 这是我的代码 import React Component from react import HeaderProduct from components heade
  • 如何删除使用 django-ckeditor 上传的图像?

    我已经在 Django 管理界面的 CKEditor 中上传了一些图像 我可以通过单击编辑器中的 图像 按钮来浏览和选择图像 然后在弹出的窗口中单击 浏览服务器 这是弹出窗口的屏幕截图 我的问题是 如何删除服务器上的图像 不幸的是这是真的
  • “Enter-PSSession -Session”,阻止调用进程,直到用户键入“exit”

    我在将 New PSSession 与 Enter PSSession session 结合使用时遇到问题 也就是说 在用户在交互式 PSSession 中键入 exit 之前 无法阻止调用进程 这是一个代码示例 s New PSSessi
  • React-router 不会在不同路径上重新挂载组件

    我的反应应用程序中有一个组件 它是一个表单 该表格用于创建新许可证或编辑现有许可证 无论哪种方式 它都只是一个组件 它会检查 componentDidMount 是哪个 pageType 添加 更新 现在我的问题是 当我使用表单编辑许可证
  • 在 C# 中枚举 Collection 的子集?

    在 C 中是否有一种好方法可以仅枚举 Collection 的子集 也就是说 我有大量对象的集合 例如 1000 个 但我只想枚举元素 250 340 有没有一种好方法可以获取集合子集的枚举器 而无需使用另一个集合 编辑 应该提到这是使用
  • 如何从 Java 7 调用 Kotlin 挂起协程函数

    我正在尝试从 Java 7 调用 Kotlin 函数 我正在使用协程 并且这个被调用的函数正在挂起 例如 suspend fun suspendingFunction Boolean return async longRunningFunc
  • Scala 元组列表到平面列表

    我有元组对列表 List String String 并想将其展平为字符串列表 List String 一些选项可能是 连接 list map t gt t 1 t 2 一个接一个交错 在您发表评论后 您似乎在要求这个 list flatM
  • 计算一系列值的 RGB 值以创建热图

    我正在尝试用 python 创建热图 为此 我必须为可能值范围内的每个值分配一个 RGB 值 我想将颜色从蓝色 最小值 更改为绿色到红色 最大值 下面的图片示例解释了我对颜色组合的看法 我们的范围是从 1 纯蓝色 到 3 纯红色 2 介于两
  • Angular2的ng-select如何实现分组?

    我正在实现多个选择下拉菜单Angular2项目按照这个link https plnkr co edit JcG8uO9nIfSGMEKdLf0Y p preview 但现在我必须在这个多选下拉列表中显示分组 那么我该如何实现呢 或者有其他插
  • Javafx 橡皮筋调整大小错误

    所以 我的橡皮筋课上有一个错误 但我似乎无法修复它 我基本上做的是 我有一个边框窗格 它是我想要调整大小的节点的外部窗格 我为这个 borderpane 指定一个宽度为 1 像素的边框 查看 css 我还为这个边框面板分配了 4 个矩形 每
  • Angular 2 - 锚链接到当前页面上的元素[重复]

    这个问题在这里已经有答案了 如果问题标题不清楚 我有一个带有某些 链接 部分的网页 因此有人可以单击该链接并转到同一模板上的元素 这并不一定意味着更改 URL 我尝试过的要点 a href Section B a a href p Cont
  • 升级到 macOS Sierra 后无法从终端运行 R

    我最近将 MacBook 更新到了 macOS Sierra 版本 10 12 3 16D32 并且我无法再直接从终端运行 R DN51ssqi kjytay R bash R command not found DN51ssqi kjyt
  • ACM 交互器冻结

    我正在尝试使用 Swing 和 ACM 交互器制作一个非常简单的程序 它直接取自课堂讲义 但在我的计算机上不起作用 当我运行它时 它可以正常运行大约半秒 然后短暂闪烁 重新加载 然后所有按钮和文本字段功能都丢失 这是代码 import ac
  • ECONNREFUSED 用于从本地主机到另一个本地主机的代理请求

    首先 我是角度新手 我正在遵循教程视频 https youtu be 2OHbjep WjQ一步步 我在这个问题上被困了近两周 并花了很多时间在其他类似的论坛上寻找解决方案 我意识到这是一个常见的错误 但在尝试了几十个左右的解决方案但没有成
  • 如何捕获整数(0)?

    假设我们有一个语句可以生成integer 0 e g a lt which 1 3 5 捕捉这个最安全的方法是什么 这是 R 打印零长度向量 整数一 的方式 因此您可以测试a长度为 0 R gt length a 1 0 可能值得重新考虑您
  • python 中的图谱聚类

    我想使用谱聚类在 python 中对图进行聚类 谱聚类是一种更通用的技术 不仅可以应用于图形 还可以应用于图像或任何类型的数据 但是 它被认为是一种特殊的技术graph聚类技术 遗憾的是 我无法在线找到 python 中的谱聚类图的示例 S
  • 使用 CSS 制作进度条动画

    所以 我在这个页面上有几个不同的进度条 http kaye at play goals http kaye at play goals 这是我的 HTML 和 CSS div class meter span style width 100
  • jQuery $(window).load(); 是否执行事件不会在没有 声明的页面上触发? (...在 Chrome 扩展内容脚本中)

    我正在开发一个可以操作网页的 Google Chrome 扩展 但在它部分加载 DOM 或完全加载 带有图像 之后 看来现在很多网站都使用 声明 或者它的一些变体 但许多其他人没有 问题主要是关于 HTML 文档类型 我不确定其他的 是否可
  • 在 VBA 中执行存储过程的两种方法,哪一种更好?

    背景 使用前端 Ms Access 2010 和后端 SQL Server 2008 Management Studio 为了执行存储过程 我一直使用一个相当漫长的过程 如下所示 in VBA Set Conn New ADODB conn
  • 如何使用 NSPredicate 过滤包含其他类的复合对象的 NSMutableSet?

    新手问题 我有 3 个类 其中 3 个是 NSOBject 的子类 收藏类 有 2 个属性 masterSong 作为 NSMutableSet 强 非原子 和listOfPlaylists 作为 NSMutableArray 强 非原子