使用 NSPredicate 通过 NSNumber 过滤自定义对象数组时遇到问题 [英] Trouble filtering array of custom objects by an NSNumber using NSPredicate

查看:57
本文介绍了使用 NSPredicate 通过 NSNumber 过滤自定义对象数组时遇到问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这应该很简单,但有些东西阻止了我使用 NSPredicate 通过 NSNumber 过滤自定义对象数组.也许它与从 JSON 转换时的数据类型有关,但我无法弄清楚.

This should be straightforward but something is preventing me from filtering an array of custom objects by NSNumber using NSPredicate. Perhaps it has something to do with the datatype when converting from JSON but I can't figure it out.

我从 JSON 中的自定义对象数组中下载数据,如下所示:

I download data from a JSON in an array of custom Objects that look like:

{"hid":"47","public":"1"}

解析 JSON 的代码如下所示:

The code to parse the JSON looks like:

 if (feedElement[@"public"] && ![feedElement[@"public"] isEqual:[NSNull null]]) {
            newMyObject.pub = feedElement[@"public"]== nil ? @"0" : feedElement[@"public"];}

对象看起来像:

#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface MyObject : NSObject
@property (nonatomic, retain) NSNumber * hid; 
@property (nonatomic, retain) NSNumber * pub;
@end
NS_ASSUME_NONNULL_END

对象被放置在一个 NSArray * myObjects

The objects are placed in an NSArray * myObjects

我的 NSPredicate 和过滤器代码如下所示:

My NSPredicate and filter code looks like:

NSPredicate *pubPred = [NSPredicate predicateWithFormat:@"pub == 1"];
NSArray *filteredArray = [myObjects filteredArrayUsingPredicate:pubPred];

当我记录 [myObjects valueForKey:@"pub"] 时,它记录为 1,1,1 等,所以我知道 pub 的值都是 1 但是结果 filteredArray 为空.

When I log [myObjects valueForKey:@"pub"], it logs as 1,1,1, etc. so I know that the values for pub are all 1 however the resulting filteredArray is empty.

我的代码可能有什么问题?

What could be wrong with my code?

感谢您的任何建议.

编辑:我在对象中将 public 更改为 pub,以防 public 是保留字,但它没有更改任何内容

Edit: I changed public to pub in the object in case public was a reserved word but it did not change anything

推荐答案

附示例代码:{"hid":"47","public":"1"}

newMyObject.pub = feedElement[@"public"]== nil ? @"0" : feedElement[@"public"];

如果 public 值存在于 JSON 中,您将使用 feedElement[@"public"] 设置 pub 属性,即意味着,它将是@"1"(带有示例),这意味着您将放置一个 NSString.
如果 public 值存在于 JSON 中,您将使用 @"0" 设置 pub 属性,这意味着您将放置一个 NSString.

In case of public value is present in JSON, you'll set pub property with feedElement[@"public"], which means, it will be @"1" (with the sample), which means you'll put a NSString.
In case of public value is present in JSON, you'll set pub property with @"0" which means you'll put a NSString.

它是否声明为 @property (nonatomic, retain) NSNumber * pub; 无关紧要,您设置的是 NSString,而不是 NSNumber.

It doesn't matter if it's declared @property (nonatomic, retain) NSNumber * pub;, you are setting a NSString, not a NSNumber.

想要一些代码测试吗?

@interface MyObject : NSObject

@property (nonatomic, retain) NSNumber *hid;
@property (nonatomic, retain) NSNumber *pub;

+(void)test;
@end

@implementation MyObject

-(id)initWithPub:(NSNumber *)pub andHID:(NSNumber *)hid {
    self = [super init];
    if (self) {
        self.pub = pub;
        self.hid = hid;
    }
    return self;
}

-(NSString *)description {
    return [NSString stringWithFormat:@"%@ pub: %@ - hid: %@", [super description], [self pub], [self hid]];
}

+(NSArray *)arrayList {
    return @[[[MyObject alloc] initWithPub:@1 andHID:@3], //Here with real NSNUmbner
             [[MyObject alloc] initWithPub:@"1" andHID:@"2"]]; //Here with NSString instead
}

+(void)test {
    NSArray *list = [MyObject arrayList];

    NSPredicate *predicateNSNumber = [NSPredicate predicateWithFormat:@"pub == %@", @1];
    NSArray *filteredNSNumber = [list filteredArrayUsingPredicate:predicateNSNumber];
    NSLog(@"Filtered-NSNumber: %@", filteredNSNumber);

    NSPredicate *predicateNSString = [NSPredicate predicateWithFormat:@"pub == %@", @"1"];
    NSArray *filteredNSString = [list filteredArrayUsingPredicate:predicateNSString];
    NSLog(@"Filtered-NSString: %@", filteredNSString);
}

输出:

$> Filtered-NSNumber: (
    "<MyObject: 0x60000024cba0> pub: 1 - hid: 3"
)
$> Filtered-NSString: (
    "<MyObject: 0x60000024d1e0> pub: 1 - hid: 2"
)

您可以声明:是的,但是您在 [[MyObject alloc] initWithPub:@"1" andHID:@"2"] 中有一个警告:不兼容的指针类型发送 'NSString *' 到 'NSNumber *' 类型的参数,是的,我有.你也应该有.

You can state: "Yeah, but you have a warning in [[MyObject alloc] initWithPub:@"1" andHID:@"2"]: Incompatible pointer types sending 'NSString *' to parameter of type 'NSNumber *', yes, I have. You should have it too.

事实上,如果你写了你的三元,你也会拥有它:

In fact, you'll have it too if you wrote your ternary if :

if (feedElement[@"public"] == nil) {
    newMyObject.pub = @"0"; //Incompatible pointer types assigning to 'NSNumber * _Nonnull' from 'NSString *'
} else {
    newMyObject.pub = feedElement[@"public"]; //Here, no warning, because it's hope you know what you are doing and setting a NSNumber here.
}

如何使用它来检查您的代码:

What about using this to your code to check:

for (MyObject *anObject in list) {
    NSLog(@"Testing: %@", anObject);
    if ([[anObject pub] isKindOfClass:[NSString class]]) {
        NSLog(@"Pub is a String");
    } else if ([[anObject pub] isKindOfClass:[NSNumber class]]) {
        NSLog(@"Pub is a NSNumber");
    }
    NSLog(@"Attempt to call -stringValue which is a NSNumber method, not a NSString one");
    NSLog(@"Attempt Call: %@\n", [[anObject pub] stringValue]);
}

你应该得到一个 -[__NSCFConstantString stringValue]: unrecognized selector sent to instance 错误,因为它实际上是一个 NSString,而不是一个 NSNumber.

You should get a -[__NSCFConstantString stringValue]: unrecognized selector sent to instance error, because it's really a NSString, not a NSNumber.

解决方案:

您需要修复解析,或更改 MyObject 中的属性类型.

You need to fix your parsing, or change the type of property in MyObject.

将属性保留为 NSNumber:

if ([feedElement[@"public"] isKindOfClass:[NSString class]]) {
     self.pub = @([feedElement[@"public"] integerValue]); //Transform it into a NSInteger, then into a NSNumber with @(someInteger)
} else ([feedElement[@"public"] isKindOfClass:[NSNumber class]]) {
    self.pub = feedElement[@"public"]; //It's already a NSNumber instance
} else {
    self.pub = @(0); //Default value because unknown class or not present 
}

这篇关于使用 NSPredicate 通过 NSNumber 过滤自定义对象数组时遇到问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆