我的应用上的用户可以选择过滤器来缩小项目范围。选择过滤器后,会发送NSNotification
,将选定过滤器数组(NSString
)传递给另一个视图控制器。
收到通知后,我可以从[notification userInfo]
中提取数组。现在,我想要做的是将新过滤器与已经为用户保存的过滤器进行比较,以便仅在它们不同时才调用服务器。这是我的方法:
- (void)applyFilters:(NSNotification *)notification {
NSArray *filters = [[notification userInfo] objectForKey:@"filters"];
if (showMyItems) {
if (![[NSSet setWithArray:filters] isEqualToSet:[NSSet setWithArray:[[PFUser currentUser] objectForKey:@"filtersMy"]]]) {
[[PFUser currentUser] setObject:[NSArray arrayWithArray:filters] forKey:@"filtersMy"];
[[PFUser currentUser] saveInBackground];
}
} else {
if (![[NSSet setWithArray:filters] isEqualToSet:[NSSet setWithArray:[[PFUser currentUser] objectForKey:@"filters"]]]) {
[[PFUser currentUser] setObject:[NSArray arrayWithArray:filters] forKey:@"filters"];
[[PFUser currentUser] saveInBackground];
}
}
}
这里我比较的是NSSet
而不是NSArray
,因为对象/字符串的顺序并不重要。我尝试做的是创建一个新数组,并通过arrayWithArray:
设置为用户的新过滤器。因此,当用户下次更改过滤器选择时,我希望新的filters
数组与为用户保存的数组(我的if语句条件)不同。但是,当我同时使用NSLog(new和saved / fetched数组)时,它们完全相同!因此if条件永远不会过去。
我对此的唯一解释是[NSArray arrayWithArray:filters]
仍以某种方式指向filters
数组。
我甚至尝试过在SO和Apple上提出的[NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:filters]]
,但结果是一样的。
有人可以发现我的问题吗?我没有选择和想法......
更新:
我现在已经粘贴了完整的方法(上面)。更多背景:
UIViewController
类showMyItems
设置为YES
(因此只调用if
语句的顶部)。在另一个例子中 - NO
,因此只有下半部分被称为showMyItems
为NO
时,我的代码按预期工作!但是当showMyItems
为YES
时,它不会......虽然代码相同。有什么想法吗?
答案 0 :(得分:0)
NSArray *temp = [[NSMutableArray alloc] initWithArray:filters copyItems:YES];
(以上适用于一级深拷贝)
对于深度复制,我到目前为止找到的最佳方法是
NSMutableArray *deepCopyArray = (NSMutableArray*)CFBridgingRelease(CFPropertyListCreateDeepCopy(kCFAllocatorDefault, (CFDictionaryRef)filters, kCFPropertyListMutableContainers));
答案 1 :(得分:0)
我已经测试了一些代码,但我不知道为什么你的If语句没有触发。以下是示例代码:
NSArray *newFilters = @[@"A",@"B",@"D"];
NSArray *oldFilters = [[NSUserDefaults standardUserDefaults] objectForKey:@"filters"];
if (![[NSSet setWithArray:newFilters] isEqualToSet:[NSSet setWithArray:oldFilters]]) {
[[NSUserDefaults standardUserDefaults] setObject:newFilters forKey:@"filters"];
[[NSUserDefaults standardUserDefaults] synchronize];
} else {
NSLog(@"Not Equal");
}
此代码将相应地响应过滤器更改。我不确定为什么你在这里创建一个新数组[[PFUser currentUser] setObject:[NSArray arrayWithArray:filters] forKey:@"filters"];
答案 2 :(得分:0)
重写我以前的方法来解决我的问题,虽然老实说我并不完全明白为什么。
- (void)applyFilters:(NSNotification *)notification {
NSArray *filters = [[notification userInfo] objectForKey:@"filters"];
NSString *key = (myItems) ? @"filtersMy" : @"filters";
if (![[NSSet setWithArray:filters] isEqualToSet:[NSSet setWithArray:[[PFUser currentUser] objectForKey:key]]]) {
[[PFUser currentUser] setObject:[NSArray arrayWithArray:filters] forKey:key];
[[PFUser currentUser] saveInBackground];
[self setUpItemsArrayWithFilters:filters];
}
}
我基本上只使用相同的代码一次,只使用不同的密钥,具体取决于当前活动的控制器。