簡體   English   中英

使用 NSPredicate 按 NSNumber 過濾自定義對象數組時遇到問題

[英]Trouble filtering array of custom objects by an NSNumber using NSPredicate

這應該很簡單,但有些東西阻止我使用 NSPredicate 通過 NSNumber 過濾自定義對象數組。 從 JSON 轉換時,它可能與數據類型有關,但我無法弄清楚。

我從 JSON 下載了一組自定義對象中的數據,如下所示:

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

解析 JSON 的代碼如下所示:

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

object 看起來像:

#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

我的 NSPredicate 和過濾器代碼如下所示:

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

當我記錄[myObjects valueForKey:@"pub"]時,它記錄為 1,1,1 等,所以我知道 pub 的值都是 1,但是生成的filteredArray是空的。

我的代碼可能有什么問題?

感謝您的任何建議。

編輯:我在 object 中將 public 更改為 pub 以防 public 是保留字但它沒有改變任何東西

帶有示例代碼: {"hid":"47","public":"1"}

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

如果 JSON 中存在public值,您將使用feedElement[@"public"]設置pub屬性,這意味着它將是 @"1"(帶有示例),這意味着您將放置一個NSString
如果 JSON 中存在public值,您將使用 @"0" 設置pub屬性,這意味着您將放置一個NSString

是否聲明@property (nonatomic, retain) NSNumber * pub;沒關系 ,您正在設置NSString ,而不是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);
}

Output:

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

您可以 state:“是的,但是在[[MyObject alloc] initWithPub:@"1" andHID:@"2"]中有警告: Incompatible pointer types sending 'NSString *' to parameter of type 'NSNumber *' ,是的,我有。你也應該有。

事實上,如果你寫了你的三元組,你也會擁有它,如果:

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.
}

如何使用它來檢查您的代碼:

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

解決方案:

您需要修復解析,或更改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 
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM