NSMutableArray : getObject method returning null - objective-c

This program should take 5 NSString's in input and print them.
I put them in an NSMutableArray.
During the loop if I try to print the NSString's they're printed correctly.
But when I try getting the objects from the array, I don't know why it returns null.
So if I try printing them in the second loop, they're all null.
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
NSAutoreleasePool* pool=[[NSAutoreleasePool alloc]init];
NSMutableArray* array;
NSString* str=[[NSString alloc]init];
char* cstr;
cstr=(char*)calloc(100,sizeof(char));
for(int i=0;i<5;i++)
{
fgets(cstr,100,stdin);
str=[NSString stringWithUTF8String:cstr];
[array addObject : str];
}
for(int i=0;i<5;i++)
{
str=[array objectAtIndex:i];
NSLog(#"%#",str);
}
[pool drain];
return 0;
}

In this line:
NSMutableArray* array;
You are declaring array, to be an NSMutableArray, but you're not setting the pointer to anything, so array is just nil.
You want to do this instead to allocate and initialize an actual instance of NSMutableArray and assign it to that pointer:
NSMutableArray* array = [[NSMutableArray alloc] init];

You haven't initialized your array. You should put: NSMutableArray *array = [[NSMutableArray alloc] init];
or better yet: NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:5];

Related

Objective-C method_exchangeImplementations result is not as expected

I'm learning Objective-C runtime, and try to use method_exchangeImplementations to exchange addObject: method and removeObject: method of NSMutableArray.
My code like this:
int main(int argc, const char * argv[]) {
#autoreleasepool {
Method removeMethod = class_getInstanceMethod(NSMutableArray.class, #selector(removeObject:));
Method addMethod = class_getInstanceMethod(NSMutableArray.class, #selector(addObject:));
method_exchangeImplementations(addMethod, removeMethod);
NSMutableArray *array = [[NSMutableArray alloc] init];
NSObject *obj = [[NSObject alloc] init];
[array removeObject:obj];
NSLog(#"%lu", (unsigned long)array.count); // expect print 1, actual print 1
[array addObject:obj];
NSLog(#"%lu", (unsigned long)array.count); // expect print 0, actual print 2
}
return 0;
}
I expect exchange add/remove function, but seems like only removeObject: has been exchange to addObject: , addObject: still is addObject to array, now I have two addObject method of NSMutableArray
I'm not sure the reason. I try to exchange other method like uppercaseString/lowercaseString of NSString, that work correct.
OK, I solved problem. Thanks #Willeke for the tip.
The real class of my array is not NSMutableArray, so use NSMutableArray.class in class_getInstanceMethod can't get correct method. Use [array class] is the answer.
int main(int argc, const char * argv[]) {
#autoreleasepool {
NSMutableArray *array = [[NSMutableArray alloc] init];
Method removeMethod = class_getInstanceMethod([array class], #selector(removeObject:));
Method addMethod = class_getInstanceMethod([array class], #selector(addObject:));
method_exchangeImplementations(addMethod, removeMethod);
NSObject *obj = [[NSObject alloc] init];
[array removeObject:obj];
NSLog(#"%lu", (unsigned long)array.count); // expect print 1, actual print 1
[array addObject:obj];
NSLog(#"%lu", (unsigned long)array.count); // expect print 0, actual print 0
}
return 0;
}

why is this not printing out a grocery list? NSMuteableArray For fast loop enumeration

#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
#autoreleasepool {
NSMutableArray *groceries;
NSString *a = (#"loaf of bread");
NSString *b = (#"stick of butter");
NSString *c = (#"big ass cookie");
[groceries addObject:a];
[groceries addObject:b];
[groceries addObject:c];
for (NSString *d in groceries){
NSLog(#"%#", d);
}
}
return 0;
}
Why is this not working? What is wrong? Thanks.
I cannot seem to figure it out at this moment, the for loop defiantly seems to be the hangup.
While you didn't initialize NSMutableArray, it's is nil. Adding object to non-initialized mutable array always give nil.
Firstly you need to initialize groceries:
NSMutableArray *groceries = [NSMutableArray new];
or more liked by me way:
NSMutableArray *groceries = #[].mutableCopy;
In your case, for example, you can declare so:
NSMutableArray *groceries = #[#"loaf of bread", #"stick of butter", #"big ass cookie"].mutableCopy;

Seg Fault when using addObject to NSMutableArray

I seem to be having a problem with the NSMutableArray.
Here's my code:
NSMutableArray *returnArray = [[NSMutableArray alloc] init];
while(condition) {
NSInteger temp = someNumber;
[returnArray addObject: temp];
}
But as soon as it hits the addObject message, the program seg faults. Any advice?
You can't add primitives like integers to an array, only objects (hence the name addObject:). If you want to add numbers, you have to convert them to an NSNumber, or one of the related classes.
You can only add objects to array and NSInteger is not an array.
NSMutableArray *returnArray = [[NSMutableArray alloc] init];
while(condition) {
[returnArray addObject: [NSNumber numberWithInt: someNumber]];
}
You need to wrap primitives such as NSInteger into an NSNumber class. You can do the following:
while(condition)
{
NSInteger temp = someNumber;
[returnArray addObject:#(temp)];
}
Or if your compiler doesn't support that syntax:
while(condition)
{
NSInteger temp = someNumber;
[returnArray addObject:[NSNumber numberWithInteger:temp]];
}

Method Creates an Array with 11 objects, All Out of Scope, Unrecognized Selector Results

Okay, so, I'm doing a simple lookup. I have an array of NSString objects and a string to search for in the array's elements.
It all seems to work up until I try to add a match to a new mutable array made to hold the search results. The stringHolder variable gets the string, and resultsCollectorArray even get the right number of new elements, but each element is empty and "out of range". Here's the method:
#implementation NSArray (checkForString)
-(NSMutableArray *) checkForString: (NSString *) matchSought
{
long unsigned numberofArrayElements;
long unsigned loop = 0;
NSRange searchResults;
NSMutableArray * resultCollectorArray = [[NSMutableSet alloc] init];
id stringHolder;
numberofArrayElements = [self count];
while (loop < numberofArrayElements) {
searchResults.length = 0;
searchResults = [[self objectAtIndex: loop] rangeOfString: matchSought options:NSCaseInsensitiveSearch];
if (searchResults.length > 0) {
stringHolder = [self objectAtIndex: loop];
[resultCollectorArray addObject: stringHolder];
}
loop++;
}
return [resultCollectorArray autorelease];
}
Once we get back to the main portion of the program, I get an unrecognized selector sent to the mutable array that was supposed to receive the result of the method. Here's the main section:
#import <Foundation/Foundation.h>
#import "LookupInArray.h"
int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSString *testString = [[NSString alloc] initWithString: #"ab"];
NSMutableString * resultString = [[NSString alloc] init];
NSArray * theArray = [[NSArray alloc] initWithObjects: ..., nil]; // Actual code has the objects
NSMutableArray *resultArray = [[NSMutableArray alloc] init];
NSUInteger arrayCount = 0;
unsigned long loops = 0;
resultArray = [theArray checkForString: testString];
arrayCount = [resultArray count];
while (loops < arrayCount){
resultString = [resultArray objectAtIndex: loops]; // Here's where we get the unrecognized selector.
NSLog(#"%#", resultString);
loops++;
}
[pool drain]; // Also, I'll release the objects later. I just want to get what's above working first.
return 0;
}
I've searched the other answers (for hours now), but didn't seen anything that solved the issue.
Any and all help would be really appreciated.
And thanks beforehand.
NSMutableArray * resultCollectorArray = [[NSMutableSet alloc] init]; is so incorrect. You are creating a mutable set and assigning it to a mutable array.
You are getting unrecognized selector because objectAtIndex: is not a valid selector for NSMutableSet. Make that statement,
NSMutableArray * resultCollectorArray = [[NSMutableArray alloc] init];
A Better way
NSArray * filteredArray = [array filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"SELF contains[cd] %#", searchString]];
You can directly filter the array using predicates. This way you do this in a single step. :)

Can a function return an object? Objective-C and NSMutableArray

I have an NSMutableArray. It's members eventually become members of an array instance in a class. I want to put the instantiantion of NSMutable into a function and to return an array object. If I can do this, I can make some of my code easier to read. Is this possible?
Here is what I am trying to figure out.
//Definition:
function Objects (float a, float b) {
NSMutableArray *array = [[NSMutableArray alloc] init];
[array addObject:[NSNumber numberWithFloat:a]];
[array addObject:[NSNumber numberWithFloat:b]];
//[release array]; ????????
return array;
}
//Declaration:
Math *operator = [[Math alloc] init];
[operator findSum:Objects(20.0,30.0)];
My code compiles if I instantiate NSMutableArray right before I send the message to the receiver. I know I can have an array argument along with the method. What I have problem seeing is how to use a function and to replace the argument with a function call. Any help is appreciated. I am interested in the concept not in suggestions to replace the findSum method.
Use autorelease to return objects you create in methods/functions.
NSMutableArray* Objects(float a, float b) {
NSMutableArray *array = [[[NSMutableArray alloc] init] autorelease];
// or: [NSMutableArray array];
[array addObject:[NSNumber numberWithFloat:a]];
[array addObject:[NSNumber numberWithFloat:b]];
return array;
}
Or simply:
NSMutableArray* Objects(float a, float b) {
return [NSMutableArray arrayWithObjects:
[NSNumber numberWithFloat:a],
[NSNumber numberWithFloat:b],
nil];
}