IOS 5:如何返回 YES on 包含:包含 2 个'identical'对象,但指针不同



我对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,那么对象将被放入ShoppingCartNSMutableArray(它是一个单例)。

检查购物车中的重复项:

为了确保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。然后,我检查getMyCustArraygetExternalCustArray中是否包含对象,并更新关于对象的附加信息并删除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;

最新更新