IOS 5:如何返回YES on包含:具有2个“相同”对象,但具有不同的指针

时间:2012-11-14 10:15:09

标签: web-services ios5 hash nsmutablearray equality

我是StackOverflow的新手,如果我忘了一些,请提前道歉 我问题中的关键因素。这是一个很长的,所以忍受我!

迭代JSON-webservice结果:

对于IOS5 iPad应用程序,我从网络服务收集JSON信息并通过:

NSData *data = [NSData dataWithContentsOfURL:url];
NSDictionary *json = 
[NSJSONSerialization JSONObjectWithData:data options:kNilOptions      
error:&error];

我将遍历返回的NSDictionary并将返回的对象及其属性存储为自定义类。

自定义类包含多个属性,包括AmountInShoppingCart - 值。

我使用此自定义类来表示我们在商店中销售的商品,因此NSMutableArray由所有返回的对象组成并显示给用户。 如果是AmountInShoppingCart value > 0,那么该对象将被放入ShoppingCart NSMutableArray(单身)。

检查ShoppingCart中的重复项:

为了确保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++;}}}

平等&amp;散列

为了实现这一点,我已经覆盖了isEqual: - 类的MyCust - 函数,以便它会查看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-webservice请求相同的结果,因为它使用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)有关,但我不太清楚我是如何实现这一点的。如果有人得到购物车系统的一些好的提示,那也总是受欢迎的。我有一半的想法将所有这些转换为Core Data,但希望在此之前拥有核心功能。

1 个答案:

答案 0 :(得分:3)

在isEqual:方法中,行“if(externalItemId!= [otherCust externalItemId])返回NO;”是错的。 我认为应该是if(![externalItemId:isEqual:[otherCust externalItemId]])返回NO;