What is the equivalent of NSNotFound for floats - ios

What if I have a method that returns a CGFloat and that method could not find an expected number, I would like to return something like NSNotFound, but that is an NSInteger.
Whats the best practice for this ?

You could use not a number (NaN).
See nan(), nanf() and isnan().
However for these issues, where there is no clearly defined non-value (it's worse with integers), then I prefer to use the following method semantics:
- (BOOL)parseString:(NSString *)string
toFloat:(CGFloat *)value
{
// parse string here
if (parsed_string_ok) {
if (value)
*value = parsedValue;
return YES;
}
return NO;
}

A pretty clean way is to wrap it into an NSNumber:
- (NSNumber *)aFloatValueProbably
{
CGFloat value = 0.0;
if (... value could be found ...) {
return #(value);
}
return nil;
}
Then you can check if the function returned nil for your non-existing value.

Related

How to append parameters to string in Objective C?

I have this method and I need to concatenating parameters so the result should be. Any idea how to do it?
getTyreLabels?width=m125.00&aspect=25&rim=13.00&season=SU&time=269742091
- (NSURL *)getTyreLabels:(NSString*)width :(NSInteger*)aspect : (NSInteger*)rim : (NSString*)season : (NSString*)pattern : (NSInteger*)time;
{
return [[self getBaseUrl] URLByAppendingPathComponent:#"getTyreLabels"];
}
I'm guessing that the string you put at the beginning is the desired output.
In which case your method should be something like...
- (NSString *)parameterStringWithWidth:(NSString *)width
aspect:(NSInteger)aspect
rim:(NSInteger)rim
season:(NSString *)season
pattern:(NSString *)pattern
time:(NSInteger)time
{
return [NSString stringWithFormat:#"getTyreLabels?width=m%#&aspect=%ld&rim=%ld&season=%#&time=%ld", width, (long)aspect, (long)rim, season, (long)time];
}
That will return the string. Not the URL but you should be able to get the point from this.
Note the way the method name is constructed. It makes it MUCH easier to call it from somewhere else as you can see what each parameter is relating to.
NSString *theString = [self parameterStringWithWidth:#"125.00" aspect:25 rim:13 season:#"SU" pattern:#"" time:269742091];
This will result in theString being the value you put in your question.
Might be you want something like this -
- (NSURL *)getTyreLabelsWithWidth:(NSString*)width
andAspect:(NSInteger)aspect
andRim:(NSInteger)rim
andSeason:(NSString *)season
andPattern:(NSString*)pattern
andTime:(NSInteger)time
{
NSString *stringToAppend = [NSString stringWithFormat#"getTyreLabels?width=%#&aspect=%d&rim=%d&season=%d&time=%d", width, aspect, rim, season, time];
return [[self getBaseUrl] URLByAppendingPathComponent: stringToAppend];
}

IOS String length comparison issue

I'm struggling with an if Comparison - I basically want to make two comparisons - both of which need to pass - Firstly a basic if a string variable is equal to 'rec' and secondly if a strings character limit is not equal to zero.
I've tried various combinations - but this is where i'm at at the mo..
ArticleObject *A = [self.articleArray objectAtIndex:indexPath.section];
NSInteger imglength = [A.arImage length];
if([A.arRec isEqual: #"rec"] ) && (imglength !=Nil){
return 195;
}
else return 50;
I get an expected identifier error on the (imglength comparison - as in this screen shot
Can anyone shed any light for me please?
There are several things you should change:
ArticleObject *A = self.articleArray[indexPath.section];
NSInteger imglength = [A.arImage length];
if (imglength && [A.arRec isEqualToString:#"rec"]) {
return 195;
} else {
return 50;
}
Don't use Nil (or nil) with primitive types.
Your parentheses are messed up:
if([A.arec isEqualToString:#"rec"] && (imglengyb !=Nil))
^--------------//here
Maybe a better way would be:
if([A.arec isEqualToString:#"rec"] && [[A.arImage length] != 0])

Comparing in objective C - Implicit conversion of 'int' to 'id' is disallowed with ARC

I i'm getting the error "Implicit conversion of 'int' to 'id' is disallowed with ARC" at the line marked with "faulty line". I guess it have something to do with that i'm checking for an integer in an array, that contains objects instead of integers.
#import "RandomGenerator.h"
#implementation RandomGenerator
NSMutableArray *drawnNumbers;
-(int) randomNumber:(int)upperNumber {
return arc4random_uniform(upperNumber);
}
-(NSMutableArray*) lotteryNumbers :(int)withMaximumDrawnNumbers :(int)andHighestNumber {
for (int i = 1; i <= withMaximumDrawnNumbers; i++)
{
int drawnNumber = [self randomNumber:andHighestNumber];
if ([drawnNumbers containsObject:drawnNumber]) { //faulty line
//foo
}
}
return drawnNumbers;
}
#end
NSArrays can only contain objective-c objects. So actually the method containsObject: is expecting an object, not an int or any other primitive type.
If you want to store number inside an NSArray you should pack them into NSNumber objects.
NSNumber *someNumber = [NSNumber numberWithInt:3];
In your case, if we assume that drawnNumbers is already an array of NSNumbers, you should change the randomNumber: generation to:
-(NSNumber*) randomNumber:(int)upperNumber {
return [NSNumber numberWithInt:arc4random_uniform(upperNumber)];
}
And then when picking it up on the lotteryNumbers method, you should:
NSNumber *drawnNumber = [self randomNumber:andHighestNumber];
Another note would go for the method you defined for lotteryNumbers. You used a really strange name for it, I think you misunderstood how the method naming works in objective-c. You were probably looking for something more like:
-(NSMutableArray*) lotteryNumbersWithMaximumDrawnNumbers:(int)maximumDrawnNumbers andHighestNumber:(int)highestNumber;
Late edit:
Objective-C now allows a way more compact syntax for creating NSNumbers. You can do it like:
NSNumber *someNumber = #(3);
And your method could be rewritten as:
-(NSNumber*) randomNumber:(int)upperNumber {
return #(arc4random_uniform(upperNumber));
}
You are using an int where an object (presumably NSNumber) is expected. So convert before use:
if ([drawnNumbers containsObject:#( drawnNumber )])

creating default vars (objects) in objective c

dumb question: lets say I'm assigning a var in a conditional statement. I don't know if the condition will be satisfied and i still want the var to be defined.. whats the correct way of writing this
example:
NSDecimalNumber *number = [[NSDecimalNumber alloc]init]; // this is pointless right?
if(x == z){
number = [whatevernum1 decimalNumberByMultiplyingBy: whatevernum2];
} else {
number = [whatevernum2 decimalNumberByDividingBy: whatevernum3];
}
// do something with number variable.
There is no need to initialize number since it will be set. Just do this:
NSDecimalNumber *number;
if(x == z){
number = [whatevernum1 decimalNumberByMultiplying: whatevernum2];
} else {
number = [whatevernum2 decimalNumberByDividing: whatevernum3];
}
// do something with number variable.
In your case number will be assigned a value one way or another. But you might have a situation like this:
if (someCondition) {
// set number to value A
} else if (anotherCondition) {
// set number to value B
}
Here, it is possible that neither condition is met. In this case you need to deal with this properly by initializing number to nil.
NSDecimalNumber *number = nil;
if (someCondition) {
// set number to value A
} else if (anotherCondition) {
// set number to value B
}
if (number) {
// process result
}
You need to declare the variable but not assign it, like this:
NSDecimalNumber *number;
if(x == z){
number = [whatevernum1 decimalNumberByMultiplying: whatevernum2];
} else {
number = [whatevernum2 decimalNumberByDividing: whatevernum3];
}
This tells the compiler that you want to use a variable named number, but don't have a value for it yet. In some cases, you may find it convenient to initialise the variable to nil rather than leaving it as a null pointer.
Normally, as others have pointed out, you would either not initialise (if you can guarantee that you will set a value, eg through an if/else pair), or you would initialise to nil.
In this simple case, a ternary statement would make your code much clearer:
NSDecimalNumber *number = x == z ? [whatevernum1 decimalNumberByMultiplyingBy:whatevernum2] : [whatevernum2 decimalNumberByDividingBy:whatevernum3];

Case insensitive compare against bunch of strings

What would be the best method to compare an NSString to a bunch of other strings case insensitive? If it is one of the strings then the method should return YES, otherwise NO.
Here's a little helper function:
BOOL isContainedIn(NSArray* bunchOfStrings, NSString* stringToCheck)
{
for (NSString* string in bunchOfStrings) {
if ([string caseInsensitiveCompare:stringToCheck] == NSOrderedSame)
return YES;
}
return NO;
}
Of course this could be greatly optimized for different use cases.
If, for example, you make a lot of checks against a constant bunchOfStrings you could use an NSSet to hold lower case versions of the strings and use containsObject::
BOOL isContainedIn(NSSet* bunchOfLowercaseStrings, NSString* stringToCheck)
{
return [bunchOfLowercaseStrings containsObject:[stringToCheck lowercaseString]];
}
Just to add a few additions to Nikolai's answer:
NSOrderedSame is defined as 0
typedef NS_ENUM(NSInteger, NSComparisonResult) {NSOrderedAscending = -1L, NSOrderedSame, NSOrderedDescending};
So if you call caseInsensitiveCompare: on a nil object you would get nil. Then you compare nil with NSOrderSame (which is 0) you would get a match which of course is wrong.
Also you will have to check if parameter passed to caseInsensitiveCompare: has to be not nil. From the documentation:
This value must not be nil. If this value is nil, the behavior is
undefined and may change in future versions of OS X.

Resources