How can I put a default value into my string if getting data from an empty key/value in a dictionary.
so [myObject setMyString:[dictionary valueForKey:@"myKey"]];
So then i开发者_如何学JAVAf I did NSString *newString = myObject.myString
I would get an unrecognized selector error
.
So again, I simply need a way to insert a default string if the key value is empty;
If dictionary
is a NSDictionary
you should probably use objectForKey
as valueForKey
is used for KVC. It works for NSDictionary
but may bite you if the key collide with some NSDictionary
KVC key, e.g. "@allKeys" or "@count".
I think the shortest is probably to do:
[dictionary objectForkey:@"myKey"] ?: @"defaultValue"
There is one terrible way of abusing the existing dictionary methods to produce a get by key or return a default value if you don't want to use a condition for some reason...
[[dictionary objectsForKeys:[NSArray arrayWithObject:@"myKey"]
notFoundMarker:@"defaultValue"]
objectAtIndex:0]
You did not hear it from me :)
What about this?
NSString *value = [dictionary valueForKey:@"myKey"];
if (!value) value = @"defaultValue";
[myObject setMyString:value];
Use [NSNull null]
for the general case, and handle it when that is returned.
In your question, you wouldn't get "unrecognised selector"; newString
would be set to nil
(as opposed to [NSNull null]
, so I suspect you might have meant something else - perhaps how to set defaults values for NSUserDefaults
?
I've done this with a simple NSDictionary extension.
NSDictionary+NSDictionaryExtensions.h
#import <Foundation/Foundation.h>
@interface NSDictionary (NSDictionaryExtensions)
- (id)objectForKey:(id)aKey defaultObject: (id) defObj;
@end
NSDictionary+NSDictionaryExtensions.m
#import "NSDictionary+NSDictionaryExtensions.h"
@implementation NSDictionary (NSDictionaryExtensions)
- (id)objectForKey:(id)aKey defaultObject: (id) defObj
{
id ret = [self objectForKey: aKey];
if ( ret == nil )
return defObj;
else
return ret;
}
@end
I can then access as follows:
NSString* str = [dict objectForKey: @"a_key" defaultObject: @"default"];
try
if ( myObject == nil ) {
[myObject setMyString:@""];
}
or
if ( [dictionary valueForKey:@"myKey"] == nil ) {
[dictionary setObject:@"" forKey:@"myKey"];
}
Whatever default value you assigned to your string it will not make myObject.myString
return "unrecognized selector error" - usually the property myString
either exists or it does not ('usually' as you can dig into the guts of the Objective-C runtime and play games, but this is rarely (if ever) what you want to do!)
What are you trying to do? If your aim is to throw an exception on myObject.myString
not being set then you can do that in the property implementation.
For example, valueForKey;
will return nil
if there is no value set for a given key, so you can check for that in your property:
- (void) setMyString:(NSString *)value
{ myString = value;
}
- (NSString *) myString
{
if (myString == nil)
@throw [NSException exceptionWithName:@"UnrecognizedSelector" reason:@"No value set for myString" userInfo:nil];
return myString;
}
Notes:
code typed at terminal, may contain typos
code assumes garbage collection/ARC on, if not you need to add appropriate retain/copy/release
But do you really want to throw an exception? You would normally only do so if the string should be set and not being so is an exceptional condition - you don't throw for default values.
As per @Paul Lynch you must check for [NSNull null] apart from nil. It is also advisable to check for the data type you are looking for:
- (id) objectForKey: (id) key withDefault: (id) defaultValue
{
id value = self[key];
if (value == nil || [value isEqual: [NSNull null]] || ![defaultValue isKindOfClass: [value class]])
{
value = defaultValue;
}
return value;
}
You can manually check for nil values as below for different types:
extension NSDictionary {
func convertToString() -> String {
let jsonData = try! JSONSerialization.data(withJSONObject: self, options: JSONSerialization.WritingOptions.prettyPrinted) as NSData!
if jsonData == nil{
return "{}"
}else {
return String(data: jsonData as! Data, encoding: String.Encoding.utf8)!
}
}
func object_forKeyWithValidationForClass_Int(aKey: String) -> Int {
// CHECK FOR EMPTY
if(self.allKeys.count == 0) {
return Int()
}
// CHECK IF KEY EXIST
if let val = self.object(forKey: aKey) {
if((val as AnyObject).isEqual(NSNull())) {
return Int()
}
} else {
// KEY NOT FOUND
return Int()
}
// CHECK FOR NIL VALUE
let aValue : AnyObject = self.object(forKey: aKey)! as AnyObject
if aValue.isEqual(NSNull()) {
return Int()
}
else if(aValue.isKind(of: NSString.self)){
return Int((aValue as! NSString).intValue)
}
else {
if aValue is Int {
return self.object(forKey: aKey) as! Int
}
else{
return Int()
}
}
}
func object_forKeyWithValidationForClass_CGFloat(aKey: String) -> CGFloat {
// CHECK FOR EMPTY
if(self.allKeys.count == 0) {
return CGFloat()
}
// CHECK IF KEY EXIST
if let val = self.object(forKey: aKey) {
if((val as AnyObject).isEqual(NSNull())) {
return CGFloat()
}
} else {
// KEY NOT FOUND
return CGFloat()
}
// CHECK FOR NIL VALUE
let aValue : AnyObject = self.object(forKey: aKey)! as AnyObject
if aValue.isEqual(NSNull()) {
return CGFloat()
}
else {
if aValue is CGFloat {
return self.object(forKey: aKey) as! CGFloat
}
else{
return CGFloat()
}
}
}
func object_forKeyWithValidationForClass_String(aKey: String) -> String {
// CHECK FOR EMPTY
if(self.allKeys.count == 0) {
return String()
}
// CHECK IF KEY EXIST
if let val = self.object(forKey: aKey) {
if((val as AnyObject).isEqual(NSNull())) {
return String()
}
} else {
// KEY NOT FOUND
return String()
}
// CHECK FOR NIL VALUE
let aValue : AnyObject = self.object(forKey: aKey)! as AnyObject
if aValue.isEqual(NSNull()) {
return String()
}
else if(aValue.isKind(of: NSNumber.self)){
return String(format:"%f", (aValue as! NSNumber).doubleValue)
}
else {
if aValue is String {
return self.object(forKey: aKey) as! String
}
else{
return String()
}
}
}
func object_forKeyWithValidationForClass_StringInt(aKey: String) -> String {
// CHECK FOR EMPTY
if(self.allKeys.count == 0) {
return String()
}
// CHECK IF KEY EXIST
if let val = self.object(forKey: aKey) {
if((val as AnyObject).isEqual(NSNull())) {
return String()
}
} else {
// KEY NOT FOUND
return String()
}
// CHECK FOR NIL VALUE
let aValue : AnyObject = self.object(forKey: aKey)! as AnyObject
if aValue.isEqual(NSNull()) {
return String()
}
else if(aValue.isKind(of: NSNumber.self)){
return String(format:"%d", (aValue as! NSNumber).int64Value)
}
else {
if aValue is String {
return self.object(forKey: aKey) as! String
}
else{
return String()
}
}
}
func object_forKeyWithValidationForClass_Bool(aKey: String) -> Bool {
// CHECK FOR EMPTY
if(self.allKeys.count == 0) {
return Bool()
}
// CHECK IF KEY EXIST
if let val = self.object(forKey: aKey) {
if((val as AnyObject).isEqual(NSNull())) {
return Bool()
}
} else {
// KEY NOT FOUND
return Bool()
}
// CHECK FOR NIL VALUE
let aValue : AnyObject = self.object(forKey: aKey)! as AnyObject
if aValue.isEqual(NSNull()) {
return Bool()
}
else {
if aValue is Bool {
return self.object(forKey: aKey) as! Bool
}
else{
return Bool()
}
}
}
func object_forKeyWithValidationForClass_NSArray(aKey: String) -> NSArray {
// CHECK FOR EMPTY
if(self.allKeys.count == 0) {
return NSArray()
}
// CHECK IF KEY EXIST
if let val = self.object(forKey: aKey) {
if((val as AnyObject).isEqual(NSNull())) {
return NSArray()
}
} else {
// KEY NOT FOUND
return NSArray()
}
// CHECK FOR NIL VALUE
let aValue : AnyObject = self.object(forKey: aKey)! as AnyObject
if aValue.isEqual(NSNull()) {
return NSArray()
}
else {
if aValue is NSArray {
return self.object(forKey: aKey) as! NSArray
}
else{
return NSArray()
}
}
}
func object_forKeyWithValidationForClass_NSMutableArray(aKey: String) -> NSMutableArray {
// CHECK FOR EMPTY
if(self.allKeys.count == 0) {
return NSMutableArray()
}
// CHECK IF KEY EXIST
if let val = self.object(forKey: aKey) {
if((val as AnyObject).isEqual(NSNull())) {
return NSMutableArray()
}
} else {
// KEY NOT FOUND
return NSMutableArray()
}
// CHECK FOR NIL VALUE
let aValue : AnyObject = self.object(forKey: aKey)! as AnyObject
if aValue.isEqual(NSNull()) {
return NSMutableArray()
}
else {
if aValue is NSMutableArray {
return self.object(forKey: aKey) as! NSMutableArray
}
else{
return NSMutableArray()
}
}
}
func object_forKeyWithValidationForClass_NSDictionary(aKey: String) -> NSDictionary {
// CHECK FOR EMPTY
if(self.allKeys.count == 0) {
return NSDictionary()
}
// CHECK IF KEY EXIST
if let val = self.object(forKey: aKey) {
if((val as AnyObject).isEqual(NSNull())) {
return NSDictionary()
}
} else {
// KEY NOT FOUND
return NSDictionary()
}
// CHECK FOR NIL VALUE
let aValue : AnyObject = self.object(forKey: aKey)! as AnyObject
if aValue.isEqual(NSNull()) {
return NSDictionary()
}
else {
if aValue is NSDictionary {
return self.object(forKey: aKey) as! NSDictionary
}
else{
return NSDictionary()
}
}
}
func object_forKeyWithValidationForClass_NSMutableDictionary(aKey: String) -> NSMutableDictionary {
// CHECK FOR EMPTY
if(self.allKeys.count == 0) {
return NSMutableDictionary()
}
// CHECK IF KEY EXIST
if let val = self.object(forKey: aKey) {
if((val as AnyObject).isEqual(NSNull())) {
return NSMutableDictionary()
}
} else {
// KEY NOT FOUND
return NSMutableDictionary()
}
// CHECK FOR NIL VALUE
let aValue : AnyObject = self.object(forKey: aKey)! as AnyObject
if aValue.isEqual(NSNull()) {
return NSMutableDictionary()
}
else {
if aValue is NSMutableDictionary {
return self.object(forKey: aKey) as! NSMutableDictionary
}
else{
return NSMutableDictionary()
}
}
}
}
精彩评论