Add NSUInteger to NSMutableArray - ios

Hello I am working on a project and I am trying to add an NSUInteger to an NSMutableArray. I am new to Objective-C and C in general. When I run the app NSLog displays null.
I'd appreciate any help anyone is able to provide.
Here is my code
-(NSMutableArray *)flipCardAtIndex:(NSUInteger)index
{
Card *card = [self cardAtIndex:index];
[self.flipCardIndexes addObject:index];
if(!card.isUnplayable)
{
if(!card.isFaceUp)
{
for(Card *otherCard in self.cards)
{
if(otherCard.isFaceUp && !otherCard.isUnplayable)
{
int matchScore = [card match:#[otherCard]];
if(matchScore)
{
otherCard.unplayable = YES;
card.unplayable = YES;
self.score += matchScore * MATCH_BONUS;
}
else
{
otherCard.faceUp = NO;
self.score -=MISMATCH_PENALTY;
}
break;
}
}
self.score -=FLIP_COST;
}
card.faceUp = !card.isFaceUp;
}
NSLog(#"%#",self.flipCardIndexes[self.flipCardIndexes.count-1]);
return self.flipCardIndexes;
}

NSArray (along with its subclass NSMutableArray) only supports objects, you cannot add native values to it.
Check out the signature of -addObject:
- (void)addObject:(id)anObject
As you can see it expects id as argument, which roughly means any object.
So you have to wrap your integer in a NSNumber instance as follows
[self.flipCardIndexes addObject:#(index)];
where #(index) is syntactic sugar for [NSNumber numberWithInt:index].
Then, in order to convert it back to NSUInteger when extracting it from the array, you have to "unwrap" it as follows
NSUInteger index = [self.flipCardIndexes[0] integerValue]; // 0 as example

You can only add objects to NSMutableArrays. The addObject accepts objects of type id, which means it will accept an object.
NSIntegers and NSUIntegers, however, are not objects. They are just defined to be C style variables.
#if __LP64__ || NS_BUILD_32_LIKE_64
typedef long NSInteger;
typedef unsigned long NSUInteger;
#else
typedef int NSInteger;
typedef unsigned int NSUInteger;
#endif
As you can see, they are just defined to be ints and longs based on a typedef macro.
To add this to your array, you need to first convert it to an object. NSNumber is the Objective C class that allows you to store a number of any type. To make the NSNumber, you will want to you the numberWithInt method, passing your variable as the parameter.
NSNumber *number = [NSNumber numberWithInt:card];
Now that your variable is wrapped in an object, you can add it to the array.
[self.flipCardIndexes addObject:number];
Finally, if you want to retrieve the element at a future time, you have to remove the object and then convert it back to an int value you can use. Call
NSNumber *number = [self.flipCardIndexes objectAtIndex:index];
Where index is the index of the card you are trying to retrieve. Next, you have to convert this value to an integer by calling integerValue.
NSUInteger *value = [number integerValue];

Related

Modify C-array in objective-c function

As an iOS programmer I sometimes delve into C to achieve faster results (well actually for fun) and I'm struggling to modify a C-array's values inside a function call. Although I think this answer may help (Modifying a array in a function in C), I don't know where to begin in implementing it.
Currently I have:
[object.guestlists enumerateObjectsUsingBlock:^(id obj, BOOL *stop) {
NSObject *someNSObject = [NSObject new];
NSInteger array[3] = {totalIncomingMales,totalIncomingFemales,
totalIncomingGuestsCount};
[self callMethod:object withCArray:cArray];
}];
- (void) callMethod:(NSObject*) object withCArray:(NSInteger*) cArray {
// do something with that object
NSInteger totalIncomingMales = cArray[0],
totalIncomingFemales = cArray[1],
totalIncomingGuestsCount = cArray[2];
// modify these integers internally so that the C-array passed in is also modified
}
Obviously this passes a pointer and therefore doesn't modify the value. I tried replacing the NSinteger * with NSInteger ** and making,
e.g. totalIncomingMales = * cArray[0], but alas I wasn't able to pass the c-array as a parameter (even with an ampersand).
Some useful material and potentially a solution to this would be much appreciated!
Not sure if I understand your question, but it seems to be trivial one:
- (void) callMethod:(NSObject*) object withCArray:(NSInteger*) cArray {
// modify these integers internally so that the C-array passed in is also modified
cArray[0] = 10;
cArray[1] = 20;
cArray[2] = 30;
}
- (void) myMethod:(NSString *) myConstString array: (NSArray *) myArray
{
NSInteger array[3] = {1,2,3};
NSLog(#"%ld %ld %ld", (long)array[0],(long)array[1],(long)array[2]);
[self callMethod:nil withCArray:array];
NSLog(#"%ld %ld %ld", (long)array[0],(long)array[1],(long)array[2]);
}
result will be:
1,2,3
after 10,20,30. No pointer trickery needed, because you are telling it is NSInteger so compiler does it for you.

Check whether the NSArray object at index is of kind NSString Or NSNumber

This is my NSArray :
(
"tag_name",
3,
"mp4_url",
4,
0,
"back_tag",
5,
1,
"part_id",
"related_list",
2
)
I need to put all the numerical values in some another array.
I used the following code to check whether the value fetched from the array was a numeric or a string, but it didn't work. Every time i get the value from an array as NSString.
for (int i=0; i<arr.count; i++) {
id obj=[arr objectAtIndex:i];
if ([obj isKindOfClass:[NSString class]])
{
// It's an NSString, do something with it...
NSLog(#"its string");
}else{
// It's an Numerical value, do something with it...
NSLog(#"its integer value");
}
}
I know that array stores only kind of objects in it, so while fetching i'm getting the value as NSString(i.e object). But is there anyway to check whether the value stored was a numeric value.
Please can anyone help me..
Thanks
You can't just turn an NSString into an NSNumber but there are ways that you can try to get he numeric value out of them.
This is one option but you could also have a look at NSNumberFormatter.
If all of the numbers are integers then you could do something like this...
// always use fast enumeration
for (NSString *string in arr) {
NSInteger integer = [string integerValue];
// have to check explicitly for 0 as a non-numeric would return 0 above
if ([string isEqualToString:#"0"]
|| integer != 0) {
// it is an integer numeric string
} else {
// it is a string
}
}

Handle NSNumber and NSInteger

Following is a code snippet i am using to add data to nsmutable array, now I am not sure on what to type cast it on while extracting, i need integer value.
Problem is that I am getting warnings of 'id' and 'NSInteger' conversion. What could be better way of extracting:
self.itemsBottom = [NSMutableArray array];
for (int i = 20; i < 30; i++)
{
[itemsBottom addObject:#(i)];
}
wanna do something like:
NSInteger itemAddressed = [self.itemsBottom objectAtIndex:itemIndex]
In this statement
[itemsBottom addObject:#(i)];
you are boxing the integer value to NSNumber.
While here
NSInteger itemAddressed = [self.itemsBottom objectAtIndex:itemIndex]
you are tried to store NSNumber to NSInteger, hence getting the error.
You can use :
NSInteger itemAddressed = [[self.itemsBottom objectAtIndex:itemIndex] integerValue];
Or in short :
NSInteger itemAddressed = [self.itemsBottom[itemIndex] integerValue];
All seems reasonable...I would think the last line would need to be...
NSInteger itemAddressed = [self.itemsBottom[itemIndex] integerValue];
Maybe?

How can an int be converted into an id?

I have an array, and the contents of it are objects of type id, but I need to turn them into type int. Is there any way I can make the array read the data as ints, or turn the id into an int?
NSArray *array = [string componentsSeparatedByString:#"\n"];
int foo = array[0]; /*Warning: Incompatible pointer to integer conversion initializing 'int' with an expression of type 'id' */
componentsSeparatedByString: docs says:
Return value
An NSArray object containing substrings from the receiver that have been divided by separator.
So your fileContents contains an array of NSStrings. fileContents[0] is then the first NSString instance in the array. And you can convert NSString to int or preferably NSInteger by calling
[string intValue];
[string integerValue];
So your code should look like this (assuming array contains at least 1 object, don't forget to check this):
int object1 = [fileContents[0] intValue];
Or even better include typecasting for better code readability
int object1 = [(NSString *)fileContents[0] intValue];
You should use intValue to convert to int.
int object1 = [fileContents[0] intValue];

EXC_BAD_ACCESS exception on accessing a property

I want to create a class that I want to serialize as XML using the property names and property values of the class. For that I created the following function in my base class (from which I will derive all my other classes):
- (NSString*) serialize
{
unsigned int outCount, i;
NSMutableString* s = [NSMutableString string];
Class currentClass = [self class];
while(currentClass != nil) {
objc_property_t *properties = class_copyPropertyList([self class], &outCount);
if(outCount > 0) {
for(i = 0; i < outCount; i++) {
objc_property_t property = properties[i];
NSString *name = [NSString stringWithCString: property_getName(property) encoding: NSUTF8StringEncoding];
[s appendFormat: #"<%#>%#</%#>", name, (NSString*)property, name];
}
}
free(properties);
}
return (NSString*)s;
}
#end
I am assuming that all the properties are (nonatomic,strong) NSString* (for now - a more sophisticated code would come later). Now for some reason when I hit the line
[s appendFormat: #"<%#>%#</%#>", name, (NSString*)property], name];
I am getting a EXC_BAD_ACCESS exception.
What am I doing wrong?
Thanks in advance!
property is coming back as a c string, not an NSString. Just change your format to print out a c string instead of trying to convert it, something like this:
[s appendFormat: #"<%#>%s</%#>", name, property, name];
Found it. Just use
NSString *value = [self valueForKey:name];
to get the property value...
When you use %# with an object, the compiler basically tries to help you by calling that object's description method. Your objc_property_t variable doesn't support that method. I think it's actually a struct...You can't just cast that to NSString. You need to decide WHAT attribute you want to print from it, and then retrieve that value from it. Similar to what you did using property_getName for retrieving the "name" attribute.

Resources