6

私は StackOverflow を初めて使用するので、質問の重要な要素を忘れていた場合は事前にお詫び申し上げます。長いので我慢してください!

JSON-webservice の結果を繰り返す:

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 での重複の確認:

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++;}}}

等価性とハッシュ

これを実現するためisEqual:に、-class のMyCust-function をオーバーライドして、-property を参照できるようにしました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];
}

2 つのアレイを同期します。

JSON Web サービスは MyCust のサイズ、高さ、および直径を使用して、それらのサイズに準拠したオブジェクトのセットを返すため、JSON Web サービスから同じ結果を要求することがあります。

そこで、次の関数を使用して、2 つの 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++;}}}

これはすべてかなりうまく機能します...

Webサービス第2弾!

ここで良い点があります。アプリが外部サプライヤーの在庫を取得するために使用する 2 つ目の JSON-WebService があります。同じMyCustオブジェクトが含まれている場合もありますが、既存のオブジェクトに解析する必要がある追加情報が含まれています。

基本的に、最初の WebService の結果を に取得し、もう 1 つを に取得しgetMyCustArrayますgetExternalCustArray。次にgetMyCustArray、 にオブジェクトが含まれているかどうかを確認getExternalCustArrayし、オブジェクトに関する追加情報を更新して、 の同様のオブジェクトを削除しますgetExternalCustArray。サプライヤーからのみ入手可能な残りのオブジェクトは、次を使用して追加されます。

mergedCustArray = [NSMutableArray arrayWithArray:[getMyCustArray arrayByAddingObjectsFromArray:getExternalCustArray]];

問題は、ユーザーが同じサイズを 2 回チェックしたときに、アプリが新しい結果を同じと見なしていないように見えることです。

ShoppingCartArray の NSLog を実行すると、次のように表示されます: (元のアイテム名は難読化されています)

最初の検索:

MyCust: SideShowBobsEarWarmers
 Hash: **2082010619**
 AmountInShoppingCart: 4
 **<MyCust: 0x81cee50>**",
    "
 MyCust: SolidSnakesCardBoardBox
 Hash: **4174540990**
 AmountInShoppingCart: 4
 **<MyCust: 0x8190d10>**" 

2 回目の検索: 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 に変換することは半分考えていますが、それを行う前にコア機能を配置したいと考えています。

4

1 に答える 1

3

isEqual: メソッドの「if (externalItemId != [otherCust externalItemId]) return NO;」の行 間違っている。if (![externalItemId:isEqual:[otherCust externalItemId]]) return NO; であるべきだと思います。

于 2012-11-14T19:30:30.030 に答える