我对StackOverflow很陌生,所以如果我忘记了一些,请提前道歉我问题中的关键因素。这是一个很长的一个,所以请耐心等待!
在JSON Web服务上的迭代结果:
对于IOS5 iPad应用程序,我从Web服务和通过收集JSON信息
NSData *data = [NSData dataWithContentsOfURL:url];
NSDictionary *json =
[NSJSONSerialization JSONObjectWithData:data options:kNilOptions
error:&error];
我将对返回的NSDictionary
进行迭代,并将返回的对象及其属性存储为一个自定义类。
自定义类包含几个属性,包括一个AmountInShoppingCart
-值。
我使用这个自定义类来表示我们在商店中销售的商品,因此NSMutableArray
由所有返回的对象组成并显示给用户。如果是AmountInShoppingCart value > 0
,那么对象将被放入ShoppingCart
NSMutableArray
(它是一个单例)。
检查购物车中的重复项:
为了确保ShoppingCart
不包含任何重复条目,我在ShoppingCartController
中有一个类似的函数(也是从SO借来的):
- (void)checkForDuplicates
{
NSMutableSet *seen = [NSMutableSet set];
NSUInteger i = 0;
NSLog(@"ShoppingCartArray count: %u",[ShoppingCartArray count]);
//Iterate over the Array to check for duplicates, and to sync the list with the
cart.
while (i < [ShoppingCartArray count]) {
id obj = [ShoppingCartArray objectAtIndex:i];
if ([seen containsObject:obj]) {
if ([obj isKindOfClass:[MyCust class]]){
MyCust *cust = [ShoppingCartArray objectAtIndex:i];
MyCust *seenCust = [seen member:obj];
seenCust.AmountInShoppingCart = cust.AmountInShoppingCart;
[ShoppingCartArray removeObjectAtIndex:i];
}} else {seen addObject:obj];
i++;}}}
平等&散列
为了实现这一点,我重写了MyCust
-类的isEqual:
-函数,以便它查看externalItemID
-属性,这是每个类对象唯一唯一的属性。
我从StackOverflow中获得了这个函数:
- (BOOL)isEqual:(id)otherObject;
{
if ([otherObject isKindOfClass:[MyCust class]]) {
MyCust *otherCust= (MyCust *)otherObject;
if (externalItemId != [otherCust externalItemId]) return NO;
return YES;
}
return NO;
}
- (NSUInteger) hash;
{
return [[self externalItemId] hash];
}
同步两个阵列:
人们可能会从JSON Web服务请求相同的结果,因为它使用MyCust的大小、高度和直径来返回一组符合这些大小的对象。
因此,我使用以下函数来检查并"同步"两个具有新结果的NSMutableArrays:
In: RESULTLISTCONTROLLER.M
- (void) syncWithCart
{
ShoppingCart *sc = [ShoppingCart sharedCart];
[sc checkForDuplicates];
NSMutableSet *listSet = [NSMutableSet setWithArray:resultList];
NSUInteger i = 0;
while (i < [sc.ShoppingCartArray count]) {
id ShopObject = [sc.ShoppingCartArray objectAtIndex:i];
if ([listSet containsObject:ShopObject])
{
MyCust *listCust = [listSet member:ShopObject];
MyCust *shopCust = ShopObject;
listCust.AmountInShoppingCart = shopCust.AmountInShoppingCart;
[listSet removeObject:ShopObject];
} else {i++;}}}
这一切都很好,直到。。。
第二次网络服务
现在好的部分来了:应用程序使用第二个JSON WebService来检索外部供应商库存。它有时包含相同的MyCust
对象,但包含必须解析为现有对象的额外信息。
我基本上将第一个WebService的结果放入getMyCustArray
,另一个放入getExternalCustArray
。然后,我检查getMyCustArray
在getExternalCustArray
中是否包含对象,并更新关于对象的附加信息并删除getExternalCustArray
中的类似对象。任何只能从供应商处获得的剩余物品都将使用添加
mergedCustArray = [NSMutableArray arrayWithArray:[getMyCustArray arrayByAddingObjectsFromArray:getExternalCustArray]];
现在的问题是,当用户两次检查相同的尺寸时,应用程序似乎并不认为新的结果是一样的。
当我对ShoppingCartArray执行NSLog时,会显示以下内容:(原始商品名称模糊)
首次搜索:
MyCust: SideShowBobsEarWarmers
Hash: **2082010619**
AmountInShoppingCart: 4
**<MyCust: 0x81cee50>**",
"
MyCust: SolidSnakesCardBoardBox
Hash: **4174540990**
AmountInShoppingCart: 4
**<MyCust: 0x8190d10>**"
第二次搜索:ResultList没有保留MyCust的AmountInShoppingCart值,所以我再次将它们从ResultList添加到ShoppingCart中。
MyCust: SideShowBobsEarWarmers
Hash: **2082010619**
AmountInShoppingCart: 4
**<MyCust: 0x81cee50>**",
MyCust: SolidSnakesCardBoardBox
Hash: **4174540990**
AmountInShoppingCart: 4
**<MyCust: 0x8190d10>**"
"
// Different Pointers, although they should be considered Equal.
MyCust: SideShowBobsEarWarmers
Hash: **2082010619**
AantalInWinkelWagen: 3
**<MyCust: 0x74bc570>**",
"
MyCust: SolidSnakesCardBoardBox
Hash: **4174540990**
AantalInWinkelWagen: 2
**<MyCust: 0x74bc7b0>**"
因此,编译器以某种方式将这些对象分配到不同的内存地址/指针中,然后中断isEqual:
函数,据我所知。
我的直觉告诉我NSCopy(able)
有问题,但我不太确定该如何实现。如果有人对购物车系统有一些好的建议,那也总是受欢迎的。我有一半的想法将所有这些转换为核心数据,但在这样做之前,我想先把核心功能准备好。
在isEqual:方法中,行"if(externalItemId!=[otherCust-externalItemId])return NO;"是错误的。我认为应该是如果(![externalItemId:isEqual:[otherCust-externalItemId]])返回NO;