1

ここに小さなテストがあります:

NSDictionary * test = @ { @"centers" : @[
                                         @{ @"id":@"12345", @"favorite":@NO },
                                         @{ @"id":@"2345", @"favorite":@NO },
                                         @{ @"id":@"345", @"favorite":@YES },
                                         @{ @"favorite":@NO }
                                         ]};

NSMutableArray * test2 = [test mutableArrayValueForKeyPath:@"centers.id"];
NSLog(@"%@",test2);

ログは次のとおりです。

(
    12345,
    2345,
    345,
    "<null>"
)

それは素晴らしいです、今、私は NSNull 値を取り除きたいです... How will I can be able to remove [NSNull Null] objects from NSMutableArray? によると これが方法です:

[test2 removeObjectIdenticalTo:[NSNull null]];
NSLog(@"%@",test2);

残念ながら、クラッシュします:

*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<__NSDictionaryI 0x7fe2ee01e970> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key id.'
*** First throw call stack:
(
    0   CoreFoundation                      0x000000010e47df35 __exceptionPreprocess + 165
    1   libobjc.A.dylib                     0x000000010e116bb7 objc_exception_throw + 45
    2   CoreFoundation                      0x000000010e47db79 -[NSException raise] + 9
    3   Foundation                          0x000000010dcb37b3 -[NSObject(NSKeyValueCoding) setValue:forKey:] + 259
    4   Foundation                          0x000000010dd44be0 -[NSArray(NSKeyValueCoding) setValue:forKey:] + 186
    5   Foundation                          0x000000010dd471cc -[NSKeyValueSlowMutableArray removeObjectAtIndex:] + 89
    6   CoreFoundation                      0x000000010e3d75a3 -[NSMutableArray removeObjectIdenticalTo:] + 131
    7   TestImageSizeReduction              0x000000010dbe6d35 -[ViewController viewDidLoad] + 1397
    8   UIKit                               0x000000010ebd2a90 -[UIViewController loadViewIfRequired] + 738
    9   UIKit                               0x000000010ebd2c8e -[UIViewController view] + 27
    10  UIKit                               0x000000010eaf1ca9 -[UIWindow addRootViewControllerViewIfPossible] + 58
    11  UIKit                               0x000000010eaf2041 -[UIWindow _setHidden:forced:] + 247
    12  UIKit                               0x000000010eafe72c -[UIWindow makeKeyAndVisible] + 42
    13  UIKit                               0x000000010eaa9061 -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 2628
    14  UIKit                               0x000000010eaabd2c -[UIApplication _runWithMainScene:transitionContext:completion:] + 1350
    15  UIKit                               0x000000010eaaabf2 -[UIApplication workspaceDidEndTransaction:] + 179
    16  FrontBoardServices                  0x0000000111f582a3 __31-[FBSSerialQueue performAsync:]_block_invoke + 16
    17  CoreFoundation                      0x000000010e3b353c __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12
    18  CoreFoundation                      0x000000010e3a9285 __CFRunLoopDoBlocks + 341
    19  CoreFoundation                      0x000000010e3a9045 __CFRunLoopRun + 2389
    20  CoreFoundation                      0x000000010e3a8486 CFRunLoopRunSpecific + 470
    21  UIKit                               0x000000010eaaa669 -[UIApplication _run] + 413
    22  UIKit                               0x000000010eaad420 UIApplicationMain + 1282
    23  TestImageSizeReduction              0x000000010dbe81f3 main + 115
    24  libdyld.dylib                       0x0000000110c50145 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

そのため、配列からインスタンスを削除する多くの方法NSNull(述語、indexesPassingTests など) を知っていますが、説明がほとんどなくてもこれが失敗する理由を本当に理解したいと思っています。

前もって感謝します。

編集: イアンの答えで与えられたプロキシの問題を防ぐための最も簡単な解決策は次のとおりです。

NSMutableArray * test2 = [[test valueForKeyPath:@"centers.id"] mutableCopy];
4

2 に答える 2

3

NSMutableArrayfrom から返される値は値のmutableArrayValueForKeyPathコピーではなく、アクセスのたびに元のオブジェクトを参照する可変プロキシ配列です。

オブジェクトを削除するように指示すると、元のオブジェクトに作用します。のオブジェクトを削除するように指示すると、失敗centers.id[NSNull null]原因になります。これらのオブジェクトは のキーと値のマッピングに応答しないためですid。そもそも何らかの結果が得られると考えるのは奇妙ですが、この[NSNull null]結果を思い通りに使用することはできません。

値だけが必要で、元のオブジェクトを変更できる操作が必要ない場合は、最初に別の方法で配列を作成することをお勧めします。おそらく述語で。

于 2015-02-16T18:00:16.043 に答える
1

NSNull は、配列が nil 値を入力として受け入れないため、配列に NULL オブジェクトを追加できる null オブジェクト型です。NULL として配列に入力する必要がある場合は、 [NSNull null] シングルトン タイプ オブジェクトを使用します。あなたの場合、空のメモリ位置のために生成されます [NSNull null] オブジェクトタイプではありません。[test2 removeObjectIdenticalTo:[NSNull null]]; を使用して削除することはできません。

NSPredicate Search を使用して削除できます

これを試してください NSPredicate Search を使用して NSArray をフィルタリングします。NSPredicate を使用して null を削除できます

NSDictionary * test = @ { @"centers" : @[
                                             @{ @"id":@"12345", @"favorite":@NO },
                                             @{ @"id":@"2345", @"favorite":@NO },
                                             @{ @"id":@"345", @"favorite":@YES },
                                             @{ @"favorite":@NO }
                                             ]};

    NSMutableArray * test2 = [test mutableArrayValueForKeyPath:@"centers.id"];
    NSLog(@"%@",test2);
    NSPredicate *predicate=[NSPredicate predicateWithFormat:@"SELF!=nil"];
    NSArray *test3=[test2 filteredArrayUsingPredicate:predicate];
    NSLog(@"%@",test3);
于 2015-02-16T18:02:03.337 に答える