I am having trouble with compatibility between NSArray and NSMutableArray? - objective-c

I am having trouble with compatibility between NSArray and NSMutableArray?
--> Incompatible Objective-C types assigning "struct NSArray *", expected "struct NSMutableArray"
NSMutableArray *nsmarrRow;
NSString *nsstrFilePath = [[NSBundle mainBundle] pathForResource: nsstrFilename ofType: nsstrExtension];
NSString *nsstrFileContents = [NSString stringWithContentsOfFile: nsstrFilePath encoding:NSUTF8StringEncoding error: NULL];
//break up file into rows
nsmarrRow = [nsstrFileContents componentsSeparatedByString: nsstrRowParse];//<--Incompatible Objective-C types assigning "struct NSArray *", expected "struct NSMutableArray"
I have tried making the "NSString declaration" to "NSMutableString"... made more problems.
thanks

You can't get a mutable array by doing
nsmarrRow = [nsstrFileContents componentsSeparatedByString: nsstrRowParse];
You will need to,
nsmarrRow = [NSMutableArray arrayWithArray:[nsstrFileContents componentsSeparatedByString: nsstrRowParse]];
Changing NSString to NSMutableString won't give you an NSMutableArray object. You will get an NSArray object just as in case of NSString. You will have to use that to get an NSMutableArray using the above method.

The componentsSeparatedByString method returns an NSArray. Try the following:
[NSMutableArray arrayWithArray:[nsstrFileContents componentsSeparatedByString: nsstrRowParse]];

Related

[__NSCFString count]: Unrecognized selector

I know this has been asked before, but there is no answer that I have found useful.
First off here is my code
// load the .csv file with all information about the track
NSError *error;
NSString *filepath = [[NSBundle mainBundle] pathForResource:#"file" ofType:#"csv" inDirectory:nil];
NSString *datastring1 = [NSString stringWithContentsOfFile:filepath encoding:NSUTF8StringEncoding error:&error];
NSArray *datarow = [datastring1 componentsSeparatedByString:#"\r"];
//fill arrays with the values from .csv file
NSArray *data_seg = [datarow objectAtIndex:0]; //segment number
NSArray *data_slength = [datarow objectAtIndex:1]; //strait length
NSArray *data_slope = [datarow objectAtIndex:2]; //slope
NSArray *data_cradius = [datarow objectAtIndex:3]; //circle radius
NSArray *data_cangle = [datarow objectAtIndex:4]; //circle angle
NSLog(#"%i", [data_seg count]);
Okay, so there is the code, and I read that is has something to do with autorelease, but I was not able to add a retain like NSArray *data_seg = [[datarow objectAtIndex:0] retain]
When I run the code, I get [__NSCFString count]: unrecognized selector sent to instance 0x9d1ad50
Any help is appreciated, I'm not good at programming, and I am very new.
componentsSeparatedByString method returns an NSArray of NSString. Every item that you extract from datarow array is an NSString and an NSString doesn't respond to 'count'. Your code starting at //fill arrays is incorrect. Every objectAtIndex call will return an NSString*.
This is another way of saying that the datatype for data_seg is NSString* (not NSArray*).
With the corrected code snippet, the problem is because data_seg is a string, and -count is not a method of NSString. It seems you think data_seg is an NSArray.
Look at the documentation for -[NSString componentsSeparatedByString:] and see what it returns -- strings! So you get back an array of strings. So what you want is:
NSString *data_seg = [datarow objectAtIndex:0]; //segment number
NSLog(#"my segment number is: %#", data_seg);

item change NSMutableArray

Can you please tell me the file string entered in the array, and then you have to change an element in this array. doing so:
NSMutableArray *user;
...
NSString* filePath1 = #"user";
NSString* fileRoot1 = [[NSBundle mainBundle] pathForResource:filePath1 ofType:#"txt"];
NSString* fileContents1 =[NSMutableString stringWithContentsOfFile:fileRoot1 encoding:NSUTF8StringEncoding error:nil];
user = [fileContents1 componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
money= [user[0] intValue]-2;
user[0]=[NSString stringWithFormat:#"%d",money];
swears
- [__NSArrayI ReplaceObjectAtIndex: withObject:]: unrecognized selector sent to instance 0x12fd4270
The componentsSeparatedByCharactersInSet: return a NSArray even if you local variable is a mutable array the value returned is not. So you will need to create a mutable copy.
Just can easily do this by call the mutableCopy on NSArray:
user = [[fileContents1 componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet] mutableCopy];

Multidimensional Arrays in Objective C

I have an NSDictionary filled with data. If this was php it might be accessed by  something like:
$data = $array['all_items'][0]['name'];
How do I do something similar in objective c? ($array would be an NSDictionary)
The equivalent code in Objective-C is:
id data = [[[array objectForKey:#"all_items"] objectAtIndex:0] objectForKey:#"name"];
Note that objectForKey: is a method of NSDictionary, and objectAtIndex: is a method of NSArray.
A shortcut in Xcode 4.5, using LLVM 4.1, is:
id data = array[#"all_items"][0][#"name"];
Also note that if "array" is an NSDictionary instance and you want to get an array of all values in the dictionary, you use the allValues method of NSDictionary:
id data = [array allValues][0][#"name"];
Of course, allValues returns an unsorted array, so accessing the array by index is not very useful. More typically, you'd see:
for (NSDictionary* value in [array allValues])
{
id data = value[#"name"];
// do something with data
}
Unfortunately the objective-c version is not as elegant syntactically as the PHP version:
NSDictionary *array = ...;
NSArray *foo = [array objectForKey#"all_items"];
NSDictionary *bar = [foo objectAtIndex:0];
NSString *data = [bar objectForKey#"name"];
For brevity, you can do this on a single line as:
NSString *data = [[[array objectForKey#"all_items"] objectAtIndex:0] objectForKey#"name"];
You should use it,
NSString *value = [[multiArray objectAtIndex:1] objectAtIndex:0];
You can look the question here

Objective-C string arrays

I have a string array as such:
NSArray *names;
names = [NSArray arrayWithObjects:
#"FirstList",
#"SecondList",
#"ThirdList",
nil];
I'm trying to assign an element of this string array to a string variable as such:
NSString *fileName = names[0]; // "Incompatible types in initialization"
or with casting
NSString *fileName = (NSString)names[0]; // "Conversion to non-scalar type requested"
I'm trying to do this, so I can use the string in a method that takes a string as an argument, such as:
NSString *plistPath = [bundle pathForResource:filetName ofType:#"plist"];
Is there no way to assign an element of a string array to a string variable?
Update from 2014: The code in this post actually would work these days since special syntactic support has been added to the framework and compiler for indexing NSArrays like names[0]. But at the time this question was asked, it gave the error mentioned in this question.
You don't use C array notation to access NSArray objects. Use the -objectAtIndex: method for your first example:
NSString *fileName = [names objectAtIndex:0];
The reason for this is that NSArray is not "part of Objective-C". It's just a class provided by Cocoa much like any that you could write, and doesn't get special syntax privileges.
NSArray is a specialized array class unlike C arrays. To reference its contents you send it an objectAtIndex: message:
NSString *fileName = [names objectAtIndex:0];
If you want to perform an explicit cast, you need to cast to an NSString * pointer, not an NSString:
NSString *fileName = (NSString *)[names objectAtIndex:0];
With the new Objective-C literals is possible to use:
NSString *fileName = names[0];
So your code could look like this:
- (void)test5518658
{
NSArray *names = #[
#"FirstList",
#"SecondList",
#"ThirdList"];
NSString *fileName = names[0];
XCTAssertEqual(#"FirstList", fileName, #"Names doesn't match ");
}
Check Object Subscripting for more information.

How add data from NSMutableString into NSArray?

is it an possible to add a value from an NSMutableString into an NSArray? Whats the snippet?
Actually, Mike is wrong. If you want to instantiate an NSArray with a single NSMutableString object, you can do the following:
NSMutableString *myString; //Assuming your string is here
NSArray *array = [NSArray arrayWithObject:myString];
There is no arrayWithElements in NSArray (see NSArray documentation)
If you want to instantiate an NSArray with a single NSMutableString object, you can do the following:
NSString *myString; //Assuming your string is here
NSArray *array = [NSArray arrayWithObjects:myString,nil];
Note that NSArray will be immutable - that is, you can't add or remove objects to it after you've made it. If you want the array to be mutable, you'll have to create an NSMutableArray. To use an NSMutableArray in this fashion, you can do the following:
NSString *myString; //Assuming your string is here
NSMutableArray *array = [[NSMutableArray alloc] init];
[array addObject:myString];
NSArray is immutable, so you cannot add values to it. You should use NSMutableArray in order to do that with the addObject: method.
NSMutableString *str = ...
NSMutableArray *array = [[NSMutableArray alloc] init];
[array addObject:str];
// You must use NSMutableArray to add Object to array
NSMutableArray *tableCellNames;
// arrayWithCapacity is a required parameter to define limit of your object.
tableCellNames = [NSMutableArray arrayWithCapacity:total_rows];
[tableCellNames addObject:title];
NSLog(#"Array table cell %#",tableCellNames);
//Thanks VKJ
An elegant solution would be this:
NSMutableString *str; //your string here
NSArray *newArray = #[str];
Using the new notation, it's a piece of cake.