How to wrap BOOL in NSValue - iphone

Having trouble wrapping a BOOL value in NSValue.
I tried this:
[NSValue valueWithPointer:[NSNumber numberWithBool:YES]]

An NSNumber is an NSValue subclass. As such,[NSNumber numberWithBool:YES] is already wrapping it in an NSValue for you.

Actually NSNumber is a heavier-weight descendant of NSValue. If you actually want to use an NSValue here's how you'd do that:
BOOL bool_value = YES;
[NSValue valueWithBytes:&bool_value objCType:#encode(BOOL)]

Here's some example code to expand on answer by Joshua Weinberg.
➤ To convert a primitive BOOL to a pseudo-Boolean object:
NSNumber* isWinning = [NSNumber numberWithBool:YES];
➤ To convert a pseudo-Boolean object to a primitive BOOL:
BOOL winner = [isWinning boolValue];
See NSNumber class reference.

Use an Objective-C literal:
#(YES)

Related

Sort NSMutableDictionary keys by object?

Okeh. Here is the deal:
Have have a NSMutualDictionary with words as keys (say names). The value objects is a NSNumber (like rating)
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
[dictionary setObject:[NSNumber intValue:1] forKey:#"Melvin"];
[dictionary setObject:[NSNumber intValue:2] forKey:#"John"];
[dictionary setObject:[NSNumber intValue:3] forKey:#"Esben"];
I want to sort them with the highest ratings first.
I know I'm going to do it like this:
[searchWords keysSortedByValueUsingSelector:#selector(intCompare:)];
But not sure how to implement intCompare. (the compare method)
Can anybody point me in the right direction?
- (NSComparisonResult) intCompare:(NSString *) other
{
//What to do here?
}
I want to get an NSArray with {Esben, John, Melvin}.
Since the objects you put into the dictionary are NSNumber instances you should change the method signature a bit. But the full implementation is really easy:
-(NSComparisonResult)intCompare:(NSNumber*)otherNumber {
return [self compare:otherNumber];
}
In fact I see no reason as to why you need to do your own intCompare: method, when you could go with the compare: that NSNumber already has.
These constants are used to indicate how items in a request are ordered.
enum {
NSOrderedAscending = -1,
NSOrderedSame,
NSOrderedDescending
};
typedef NSInteger NSComparisonResult;
That is taken from Apple's dev documentataion on Data types... now all you have to do is check which one is bigger. All of this is done for you though. Simply pass in #selector(compare:) and that should do it. As your values are NSNumbers and NSNumber implements the compare: function. Which is what you want :)
NSArray *sortedArray = [searchWords sortedArrayUsingSelector:#selector(compare:) ];
or you might well as used, here is the implementation of your intCompare selector
- (NSComparisonResult) intCompare:(NSString *) other
{
int myValue = [self intValue];
int otherValue = [other intValue];
if (myValue == otherValue) return NSOrderedSame;
return (myValue < otherValue ? NSOrderedAscending : NSOrderedDescending);
}

Boolean inside property list (Simple!)

I'm writing a small application right now and I got problems while reading out a property list...
My exact question is: How can I read out a boolean from the property list? Or better how can I read out this boolean from a NSDictionary?
Thanks, mavrick3.
The objects are stored as NSNumber objects, so to retrieve the BOOL you should use this method:
BOOL myBool = [someNSNumberObject boolValue];
To retrieve from a dictionary do something like this:
BOOl myBool = [[someDictionary objectForKey:#"someKey"] boolValue];
Documentation here: http://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/Reference/Reference.html#//apple_ref/occ/instm/NSNumber/boolValue
Try storing the BOOL as a NSNumber ... then adding that to the Dictionary.
A simple example :
BOOL answered = YES;
NSNumber *answeredAsNumber = [NSNumber numberWithBool:answered];
[dict setObject:answeredAsNumber forKey:#"isAnswered"];
BOOL retrievedAnswered = [[dict objectForKey:#"isAnswered"] boolValue];
A BOOL should be stored as a NSNumber and you can access the BOOL value by saying
BOOL myvalue = [aNSNumber boolValue]

How do I store an NSRange in a NSMutableArray or other container?

Here's what I want to do:
NSRange r = NSMakeRange(0,5);
id a = [NSMutableArray a];
[a addObject: r]; // but NSRange is not a NSObject *
With a boolean, I'd use code like this:
[a addObject: [NSNumber numberWithBool: YES]];
or with an integer:
[a addObject: [NSNumber numberWithInteger: 3]];
So what's the equivalent with a NSRange? What I don't really want to do is create my own subclass of NSObject to accomplish this. Surely there's a way with what Apple's already provided?
Use NSValue's +valueWithRange:. To retrieve the range structure back, use the property rangeValue.
[a addObject:[NSValue valueWithRange:r]];
...
NSRange r = a[4].rangeValue;
[NSValue valueWithRange:r];
and get it back out with:
NSRange r = [rangeObject rangeValue];
If you need to store the NSRange in a property list, you can also turn an NSRange into an NSString using the NSStringFromRange function. And then, you can turn that string back into a range using the NSRangeFromString function.
One other option might be to add those ranges into an NSIndexSet, depending on how you intend to use them next.

How to convert and compare NSNumber to BOOL?

First I convert BOOL value to NSNumber in order to put it into NSUserDefaults. Later I would like to retrieve the BOOL value from the NSUserDefaults, but obviously I get NSNumber instead of BOOL. My questions are?
how to convert back from NSNumber to BOOL?
How to compare NSNumber to BOOL value.
Currently I have:
if (someNSNumberValue == [NSNumber numberWithBool:NO]) {
do something
}
any better way to to the comparison?
Thanks!
You currently compare two pointers. Use NSNumbers methods instead to actually compare the two:
if([someNSNumberValue isEqualToNumber:[NSNumber numberWithBool:NO]]) {
// ...
}
To get the bool value from a NSNumber use -(BOOL)boolValue:
BOOL b = [num boolValue];
With that the comparison would be easier to read for me this way:
if([num boolValue] == NO) {
// ...
}
Swift 4:
let newBoolValue = nsNumberValue.boolValue
NSUserDefaults has two methods to transparently operate with booleans:
- (BOOL)boolForKey:(NSString *)defaultName
- (void)setBool:(BOOL)value forKey:(NSString *)defaultName
The ONLY way I managed to finagle a NSNumber's "booleanity" from its NSConcreteValue(doh!) was with the following...
id x = [self valueForKey:#"aBoolMaybe"];
if ([x respondsToSelector:#selector(boolValue)] &&
[x isKindOfClass:objc_getClass("__NSCFNumber")])
[self doSomethingThatExpectsABool:[x boolValue]];
Every other trick... FAILED. Buyer beware, this isn't foolproof (__NSCFNumber may well be platform/machine specific - it is solely Apple's implementation detail)... but as they say.. nothing else worked!

NSMutableDictionary lookup based on object's address or value when dealing with NSNumber?

If you store NSNumber* as a key to NSMutableDictionary, does it do the lookup later based on the key's address or stored value? It seems that if I store NSNumber in two dictionaries with the value from one serving as the key to the other, sometimes, the key isn't found in the 2nd dictionary even though I'm certain it's in there.
What I'm trying to do is the following:
// fetch the items from Coredata and create two different lookups
NSArray *existingActions = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
for (SomeObject *someObject in existingActions)
{
NSNumber *actionId = [someObject actionId];
[actionMap setObject:someObject forKey: actionId];
NSNumber *positionId = [someObject positionId];
[positionMap setObject: actionId forKey: positionId];
}
// later on, I'm trying to print out the values from both lookups now
NSEnumerator *enumerator = [positionMap keyEnumerator];
NSNumber *positionId;
while ((positionId = (NSNumber *)[enumerator nextObject]))
{
NSNumber *actionId = (NSNumber *)[positionMap objectForKey:positionId];
SomeObject * myObj = (SomeObject *) [actionMap objectForKey:actionId];
NSLog(#"myObj: %#", myObj];
}
// This way yields the same result as above:
NSNumber *positionId = [NSNumber numberWithInt: 7]; // filled out by client
NSNumber *actionId = (NSNumber *)[positionMap objectForKey:positionId];
SomeObject *myObj = (SomeObject *)[actionMap objectForKey: actionId];
Often, myObj is null because objectForKey can't seem to find the object associated with actionId in the actionMap dictionary.
As an additional note, the SomeObject class derives from 'NSManagedObject'. The documentation for setObject:forKey: notes for the parameters passed in:
aKey: The key for value. The key is
copied (using copyWithZone:; keys must
conform to the NSCopying protocol).
The key must not be nil.
Is it due to the fact that copyWithZone may be different with NSManagedObject classes?
What am I doing wrong here?
it uses the value that -hash returns.
It turns out that the problem was from the fact that actionId property returned by [someObject actionId] is a weak reference and you can't store it in NSDictionary without making a copy of it.
Instead of:
NSNumber *actionId = [someObject actionId];
[actionMap setObject:someObject forKey: actionId];
this works:
NSNumber *actionId = [NSNumber numberWithInt: [[someObject actionId] intValue]];
[actionMap setObject:someObject forKey: actionId];
You can use NSMapTable like an NSDictionary but without copying the keys