xcode 我可以在对象的属性上使用 [NSArray containsObject:] 函数吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15337709/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can I use the [NSArray containsObject:] function on attributes of objects?
提问by Thomas Johannesmeyer
Background Information:
背景资料:
I program an iOS application that contains 2 galleries: A local gallery and a server gallery. When the user updates the server gallery and merges it into his local one, the app should only download the new images.
我编写了一个包含 2 个画廊的 iOS 应用程序:一个本地画廊和一个服务器画廊。当用户更新服务器图库并将其合并到他的本地图库时,应用程序应该只下载新图像。
To minimize memory consumption I save the images and fill the arrays with instances of an ImageEntity
class with following attributes: fileName, filePath& votingStatus.
为了最大限度地减少内存消耗,我保存图像并使用ImageEntity
具有以下属性的类的实例填充数组:fileName、filePath和VotingStatus。
I tried to use following logic to check if the image already exists:
我尝试使用以下逻辑来检查图像是否已存在:
for (ImageEntity *imageEntity in self.serverImagesArray) {
if (![self.localImagesArray containsObject:imageEntity]){
[self.localImagesArray addObject:imageEntity];
}
}
But because each entity is a separate object it will always be added.Each entity has a unique fileNamethough.
但是因为每个实体都是一个单独的对象,所以它总是会被添加。不过,每个实体都有一个唯一的文件名。
Question:Can I somehow extend the [NSArray containsObject:]
function to check if one object in the array has an attribute equal to "someValue"? (When I use Cocoa-Bindings in combination with an ArrayController, I can assign attributes of array elements - I would like to access the attributes similar to this).
问题:我能否以某种方式扩展[NSArray containsObject:]
函数以检查数组中的一个对象是否具有等于“someValue”的属性?(当我将 Cocoa-Bindings 与 ArrayController 结合使用时,我可以分配数组元素的属性 - 我想访问与此类似的属性)。
I know that I could use compare each entity of the local array to each element on the server array. I would have to do O(n^2) comparisonsthough and the gallery may contain several hundred images.
我知道我可以使用将本地数组的每个实体与服务器数组上的每个元素进行比较。不过,我必须进行 O(n^2) 次比较,并且图库可能包含数百张图片。
Bonus question:Am I already doing this without realizing it? Does anybody have details about Apple's implementation of this function? Is there some fancy implementation or are they just iterating over the array comparing every element?
额外问题:我是否已经在不知不觉中这样做了?有没有人有关于苹果实现这个功能的详细信息?是否有一些奇特的实现,或者他们只是在比较每个元素的数组上迭代?
回答by Eimantas
The way I do it is use valueForKey:
in combination with containsObject:
. So in your case you should collect all file names of the array and then check if the array contains specific file name you need:
我这样做的方式是valueForKey:
与containsObject:
. 因此,在您的情况下,您应该收集数组的所有文件名,然后检查数组是否包含您需要的特定文件名:
NSArray * fileNames = [fileEntityObjects valueForKey:@"fileName"];
BOOL contains = [fileNames containsObject:@"someFilename.jpg"];
This would work if fileName
is property of every object in fileEntityObjects
array.
如果fileName
是fileEntityObjects
数组中每个对象的属性,这将起作用。
Update
更新
Yes, you can do this with NSPredicate
as well:
是的,你也可以这样做NSPredicate
:
NSPredicate * predicate = [NSPredicate predicateWithFormat:@"SELF.fileName = %@", "someFileName.jpg"];
NSArray * filteredArray = [fileEntityObjects filteredArrayUsingPredicate:predicate];
Note though that instead of boolean you'd get an array of objects having that filename.
请注意,您将获得具有该文件名的对象数组,而不是布尔值。
回答by Nikolai Ruhe
As this question is tagged "performance" I'm adding another answer:
由于这个问题被标记为“性能”,我添加了另一个答案:
To avoid the n^2 comparisons we have to find a faster way to detect images that are already present. To do this we use a set that can perform lookups very quickly:
为了避免 n^2 比较,我们必须找到一种更快的方法来检测已经存在的图像。为此,我们使用一个可以非常快速地执行查找的集合:
NSMutableSet *localFileNames = [NSMutableSet set];
for (ImageEntity *imageEntity in self.localImagesArray)
[localFileNames addObject:imageEntity.fileName];
Then we iterate over the server images as before. The previous containsObject:
is replaced by the fast set lookup:
然后我们像以前一样迭代服务器图像。前面的containsObject:
被快速设置查找取代:
for (ImageEntity *imageEntity in self.serverImagesArray) {
if ([localFileNames member:imageEntity.fileName] == nil)
[self.localImagesArray addObject:imageEntity];
}