NSDictionaryキーが存在するかどうかを確認する方法を検索し、解決策を考え出しました。しかし、それでも、キーにnull値を追加することを示すエラーがスローされます。私のコードが正しいかどうかはわかりません。誰かこれについて何か考えがあれば私を助けることができます。
NSDictionary *result;
id myImageURL = [result objectForKey:@"url"];
if ((NSNull *)myImageURL == [NSNull null])
myImageURL = @"";
id myImage = [result objectForKey:@"image"];
if ((NSNull *)myImage == [NSNull null])
myImage = @"";
Nullが何も追加していないかどうか、および値を追加していないかどうかを確認します。しかし、それでも理由がわからないエラーが発生します。
/****OUTPUT*****/
2011-08-11 14:56:06.668 Tab_Table_Win[6510:207] RESULTS : {
image = "<UIImage: 0xbc332c0>";
url = "http://a3.twimg.com/profile_images/999228511/normal.jpg";
}
2011-08-11 14:56:06.669 Tab_Table_Win[6510:207] url : http://a3.twimg.com/profile_images/999228511/normal.jpg
2011-08-11 14:56:06.670 Tab_Table_Win[6510:207] IMage : <UIImage: 0xbc332c0>
/*****Breaks Here ***/
2011-08-11 14:56:06.876 Tab_Table_Win[6510:207] RESULTS : {
}
2011-08-11 14:56:06.878 Tab_Table_Win[6510:207] url : (null)
2011-08-11 14:56:06.879 Tab_Table_Win[6510:207] IMage : (null)
2011-08-11 14:56:06.881 Tab_Table_Win[6510:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary setObject:forKey:]: attempt to insert nil key'
トミーはこれを完全に説明しました。
私がお勧めするのは、次のようなNSDictionaryクラスの拡張を作成することです。
#import <Foundation/Foundation.h>
@interface NSDictionary (Safety)
- (id)safeObjectForKey:(id)aKey;
@end
そして実装ファイル:
#import "NSDictionary+Safety.h"
@implementation NSDictionary (Safety)
- (id)safeObjectForKey:(id)aKey {
NSObject *object = self[aKey];
if (object == [NSNull null]) {
return nil;
}
return object;
}
@end
そして、コードで[dictionary objectForKey:@"keyName"];
を使用する代わりに、
[dictionary safeObjectForKey:@"keyName"];
このように、Tommyが説明したように、nilにメソッド呼び出しを送信すると、アプリはクラッシュしませんが、オブジェクトはnil値を取得します。
お役に立てれば。
正解は次のとおりです。
NSDictionary *result;
NSURL *myImageURL = [result objectForKey:@"url"];
UIImage *myImage = [result objectForKey:@"image"];
/**** Correct way ****/
if (myImageURL != nil && myImage != nil) {
[images setObject:myImage forKey:myImageURL];
}
説明ありがとうございました。
以下の答えが私にとってうまくいきました:
https://stackoverflow.com/a/2784675/936957
if ([dictionary objectForKey:key]) {
// previously stored data for "key"
}
また、次のコマンドを使用して、辞書内のキーの配列を取得できます。
[dictionary allKeys]
辞書から返されているオブジェクトがnullかどうかを確認しようとするたびに、これを行います。
id obj = [myDictionary objectForKey:entityKeyName];
if (obj == [NSNull null]) {
// do something
}
次に、コードでは次のようになります。
NSDictionary *result;
NSString *myImageURL = [result objectForKey:@"url"];
if (myImageURL == [NSNull null])
myImageURL = @"";
それが私があなたのコードで行うことです。
また、念のため、NSDictionaryの結果は定義されていますか?コードでは、設定されているものは何もありません。呼び出された結果を使用する予定の変数として定義されているだけです
キーのオブジェクトが存在しない場合、NSDictionaryはnil
を返します。 NSNull
は実際のオブジェクトなので、別物です。これは、値があったことを記録できることとその値をnullとして記録できることと、値があったかどうかを記録しないことの違いに似ています。それはまた、単なるオブジェクトではなく、オブジェクトへのポインターの間接参照についてCで考えることにも少し依存しているので、その観点からは完全に意味的には楽しいものではありません。
Objective-Cでは、nil
にメッセージを送信でき、結果はnil
(または0)であることが保証されます。したがって、C++の場合のように、コードが安全なオブジェクト参照を確保するように設計されている場合、実行していることは不要です。次のような複合ステートメント:
object = [[Type alloc] init];
Allocが失敗してnil
を返しても、常に明示的に安全です。発生するのは、init
を呼び出しても何も実行されず、nil
の送信結果が原因でオブジェクトの値がinit
になることです。 to nil
もnil
です。
そうは言っても、ビルとエマニュエルによって提供された答えは正しいはずです。結果を直接nil
と比較するか、暗黙的にゼロと比較します。後でクラッシュが発生する場合は、myImageUrl
およびmyImage
がNSString
以外の型であることが期待されているためと考えられます(タイプレスid
を元のコードで使用して)、応答しないメッセージを送信しました。
この別のオプション:
if (![result objectForKey:@"image"])
{
NSLog(@"doesn't exist");
}
if ([result objectForKey:@"image"])
{
NSLog(@"exist");
}
NSDictionary *result;
NSString *myImageURL = [result objectForKey:@"url"];
if (myImageURL == NULL)
myImageURL = @"";
NSString *myImage = [result objectForKey:@"image"];
if (myImageURL == NULL)
myImage = @"";
NULLクラスを考え直すのではなく、それが機能するかどうかを確認します。
それは私にとってはうまくいかなかった、私はそれをこのように考え出した
id myImageURL = [result objectForKey:@"url"];
if ([myImageURL isKindOfClass:[NSNull class]])
myImageURL = @"";
@Iomecがほとんど持っていた実際の答えはここにあります
UIImage *myImage = ([result objectForKey:@"image"] != [NSNull null] ? [result objectForKey:@"image"] : nil);
それが実際の正解です。なぜなら、それはnullであり、myImage = [receivedObject ...];と言うときです。次に、myImage = nilの場合、実行中のバグでない場合、例外であるクラスにnull値(nil)をキャストしていることになります。
1)NSNull null値をテストする2)nilでない場合は割り当てる
コードにまだバグがない場合は、1つのバックグラウンドで8つのアプリを実行しているときに本番環境で動作します。
Nullable辞書objectForKey
inを呼び出すと、アプリがクラッシュするため、クラッシュを回避するためにこの方法でこれを修正しました。
- (instancetype)initWithDictionary:(NSDictionary*)dictionary {
id object = dictionary;
if (dictionary && (object != [NSNull null])) {
self.name = [dictionary objectForKey:@"name"];
self.age = [dictionary objectForKey:@"age"];
}
return self;
}
JSONKitでも同じ問題が発生しました。そこに実装があります
- (id)objectForKey:(id)aKey
{
[...]
return((entryForKey != NULL) ? entryForKey->object : NULL);
}
したがって、オブジェクトが存在しない場合、これは間違いなくNULLを返します。次のようにチェックします
NSArray* array = [myDictionary objectForKey:@"a"];
if((NSNull*)arrays!=[NSNull null])
{
[...]
}
1. Results Dictionary after JSON parsing:
//if hits success
{"result":{"action":"authentication","statusCode":"200","statusMsg":"No
error, operation
successful.","count":1,"data":{"apiToken":"509e6d21-4f69-4ded-9f3d-4537e59e6a3a","userId":8,"role":"Bidder","firstName":"bidder","lastName":"bidder","emailAddress":"[email protected]","countiesCovered":"21,16,11,1,2,14,32,3,4,25,13,15,5,41,43,6,12,7,24,39,17,36,42,44,29,40,8,18,19,27,9,28,23,10,33,26,35,20,30,22,34,31"}}}
//Data is Dictionary inside Result
-----------------------------------------------------------------------
I had an error showing : NULL DATACould not cast value of type 'NSNull' (0xda7058) to 'NSDictionary' (0xda6d74) and the result was
the following.
({"result":{"action":"authentication","statusCode":"204","statusMsg":"Invalid
Username or Password","count":null,"data":null}})
I fixed the Null check of dictionary.
if (result.objectForKey("data") is NSNull)
{
print ("NULL DATA")
}
else
{
let data = result["data"]as! NSDictionary
print (data)
}
IS nil。であることを確認するだけでなく、文字列ではないことを確認することで、もう少し安全性を高めたい場合があります。望まないかもしれません。)
id myImageURL = [result objectForKey:@"url"];
if (![myImageURL isKindOfClass:[NSString class]]) {
myImageURL = @"";
}