web-services - IOS 5 : How to return YES on contains: with 2 'identical' objects, 但具有不同的指针

标签 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 值 > 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++;}}}

相等和哈希

为了实现此目的,我重写了 MyCust 类的 isEqual: 函数,以便它查看 externalItemID-property,这是每个类对象唯一绝对唯一的属性。

我从 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 的大小、高度和直径来返回一组符合这些大小的对象。

因此,我使用以下函数来检查两个 NSMutableArray 并将其与新结果“同步”:

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;”是错的。 我认为应该是 if (![externalItemId:isEqual:[otherCust externalItemId]]) return NO;

关于web-services - IOS 5 : How to return YES on contains: with 2 'identical' objects, 但具有不同的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13376829/

相关文章:

java - 我可以将 Web 服务作为 HTTP 请求调用吗?

iphone - UILabel setText 在 vi​​ewWillAppear 中不起作用

xcode - NSUserDefaults 不保存

git - git中的哈希冲突

java - 尝试向 Web 服务发送 SOAP 请求时出现 WS 安全错误

web-services - 在 j2me 中使用 WSDL 文件的 stub 文件

web-services - Web 服务应该是事务性的吗?

ios - 自定义应用程序中的 UITableview 部分

perl - 双箭头 (=>) 运算符在 Perl 中如何工作?

hash - :exists in raku 意外失败