[英]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.