Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 更快的MPMediaItems NSMutableArray排序?代码审查_Objective C_Ios_Sorting_Nsmutablearray - Fatal编程技术网

Objective c 更快的MPMediaItems NSMutableArray排序?代码审查

Objective c 更快的MPMediaItems NSMutableArray排序?代码审查,objective-c,ios,sorting,nsmutablearray,Objective C,Ios,Sorting,Nsmutablearray,我对iOS编程已经有几周了,还有很多东西要学。我有一个包含MPMediaItems的NSMutableArray,但它大约慢10秒,有1200个项目,我正在寻找一种更快的方法 我的最终目标是拥有一个MPMediaItemCollection项目数组,每个项目代表一个相册。我无法从MPMediaQuery(据我所知)获取此信息,因为我需要从播放列表中获取歌曲。因此,我正在对从特定播放列表(“过去4个月”)中获得的歌曲进行排序,然后构建自己的收藏阵列。正如我所说,下面的方法有效,但速度非常慢。即使我

我对iOS编程已经有几周了,还有很多东西要学。我有一个包含MPMediaItems的NSMutableArray,但它大约慢10秒,有1200个项目,我正在寻找一种更快的方法

我的最终目标是拥有一个MPMediaItemCollection项目数组,每个项目代表一个相册。我无法从MPMediaQuery(据我所知)获取此信息,因为我需要从播放列表中获取歌曲。因此,我正在对从特定播放列表(“过去4个月”)中获得的歌曲进行排序,然后构建自己的收藏阵列。正如我所说,下面的方法有效,但速度非常慢。即使我只按MPMediaItemPropertyAlbumTitle排序,也需要大约4秒钟(iPhone4S)


编辑:我应该提到,我尝试了排序描述符,但我无法获得工作的密钥。例如

NSSortDescriptor *titleDescriptor = [[NSSortDescriptor alloc] initWithKey:@"MPMediaItemPropertyAlbumTitle" ascending:YES];
这将返回一个错误

[<MPConcreteMediaItem 0x155e50> valueForUndefinedKey:]: this class is not key value coding-compliant for the key MPMediaItemPropertyAlbumTitle.
你需要了解

然后您的排序将像
return[songs SortedArrayingDescriptors:sortDescriptors]一样简单并且应该更快


编辑:根据OP,MPMediaItem类不符合KVC,因此我将取消回答。

根据@cdelacroix的建议,我重新实现了我的比较块以级联三个排序键,仅在高阶键相同时检查低阶键。这导致排序的执行时间减少了50%以上。尽管如此,它并没有我想要的那么快,所以如果有人有更好的答案,请发布它

以下是旧时代与新时代(1221项):

4S执行时间=10.8,执行时间=4.7

3GS执行时间=21.6,执行时间=9.3

有趣的是,从for循环切换到数组副本的mutableCopy似乎并没有改善情况。如果有什么区别的话,mutableCopy可能慢了十分之一秒(有人在mutableCopy上做过基准测试吗?)。但是我把零钱留了下来,因为它看起来干净多了

最后,注意检查唱片集标题==nil。请注意,compare认为任何具有nil值的内容始终与其他内容相同。列表中的一张专辑没有标题集,没有这项检查,排序顺序就搞砸了

MPMediaQuery *query = [MPMediaQuery playlistsQuery];
NSArray *playlists = [query collections];
NSMutableArray *songArray = [[NSMutableArray alloc] init];

for (MPMediaItemCollection *playlist in playlists) {
    NSString *playlistName = [playlist valueForProperty: MPMediaPlaylistPropertyName];
    NSLog (@"%@", playlistName);
    if ([playlistName isEqualToString:@"Last 4 months"]) {

        songArray = [[playlist items] mutableCopy ];

        [songArray sortUsingComparator:^NSComparisonResult(id a, id b) {
            NSComparisonResult compareResult;

            NSString *first1 = [(MPMediaItem*)a valueForProperty:MPMediaItemPropertyAlbumTitle];
            if(first1 == nil) first1 = @" "; // critical because compare will match nil to anything and result in NSOrderedSame
            NSString *second1 = [(MPMediaItem*)b valueForProperty:MPMediaItemPropertyAlbumTitle];
            if(second1 == nil) second1 = @" ";  // critical because compare will match nil to anything and result in NSOrderedSame
            compareResult = [first1 compare:second1];

            if (compareResult == NSOrderedSame) {
                NSString *first2 = [(MPMediaItem*)a valueForProperty:MPMediaItemPropertyAlbumPersistentID];
                NSString *second2 = [(MPMediaItem*)b valueForProperty:MPMediaItemPropertyAlbumPersistentID];
                compareResult = [first2 compare:second2];
                if(compareResult == NSOrderedSame) {
                    NSString *first3 = [(MPMediaItem*)a valueForProperty:MPMediaItemPropertyAlbumTrackNumber];
                    NSString *second3 = [(MPMediaItem*)b valueForProperty:MPMediaItemPropertyAlbumTrackNumber];
                    compareResult = [first3 compare:second3];
                }
            }
            return compareResult;
        }];
    }
}

我知道这是一个旧的线程,但我认为澄清OPs排序代码为什么不起作用很重要,这样任何遇到此代码的人都不会推迟使用NSSORTDescriptor

守则:

[[NSSortDescriptor alloc] initWithKey:@"MPMediaItemPropertyAlbumTitle" ascending:YES];
应该是:

[[NSSortDescriptor alloc] initWithKey:MPMediaItemPropertyAlbumTitle ascending:YES];
作为MPMediaItemPropertyAlbumTitle保存密钥的名称


我已经多次使用此代码。

for循环中有1200项。你很幸运能分别得到10秒和4秒!将MPMediaItemCollection中的所有项放入NSMutableArray的更好方法是什么?但是,即使忘记了for循环,排序也只发生一次,而且仍然需要很长时间。为此,请使用
[songs mutableCopy]
,谢谢!是的,这很有帮助。我尝试了排序描述符,但失败了,错误为[valueForUndefinedKey:]:此类不符合键MPMediaItemPropertyAlbumTitle的键值编码。这是一个NSSortDescriptor*titleDescriptor=[[NSSortDescriptor alloc]initWithKey:@“MPMediaItemPropertyAlbumTitle”升序:是];Hu,我并不期望一个新类不符合KVC。如果在Media Player框架文档中找不到任何相关内容,您仍然可以通过逐个比较每个术语(一个键接一个键)并在比较结果不一致时立即返回来优化比较方法。这将避免为此构建字符串,并且在性能方面应该更好。不过,我希望有人能以更好、更友好的方式来。
[[NSSortDescriptor alloc] initWithKey:MPMediaItemPropertyAlbumTitle ascending:YES];