-7

There are many, many similar questions to this, but I have tried every conceivable thing and am pulling my hair out trying to get this to work!

I have an array, which is passed down from other viewcontrollers, and is deeply embedded in my code. I read this in to the viewcontroller where I need to use this, and I can print this out using:

NSLog(@"array = %@", myarray);

Which returns:

2015-08-29 12:35:27.330 myapp[2679:234549] array = {
date1 = 2000;
date2 = 2010;
reference = 8;
text = "test 4";
}

So the array exists fine, and I can access it fine.

But I can't seem to be able to do the most easiest thing and use these values from the array!

I have tried simply accessing the first row by doing:

NSString *row1 = myarray[0];

But this crashes the app.

I need to access the data from this array, so that I can populate a table with the values.

Can someone help???

crash log:

2015-08-29 12:40:05.738 myapp[2721:236045] -[__NSCFDictionary objectAtIndexedSubscript:]: unrecognized selector sent to instance 0x7fecd3702500 2015-08-29 12:40:05.742 myapp[2721:236045] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary objectAtIndexedSubscript:]: unrecognized selector sent to instance 0x7fecd3702500'

R2D2
  • 2,620
  • 4
  • 24
  • 46
  • 4
    Your "array" is a `Dictionary` as the NSLog output and the error message reveals. – vadian Aug 29 '15 at 11:52
  • `__NSCFDictionary` appers in the exception message. Read. Think. Still nothing? – The Paramagnetic Croissant Aug 29 '15 at 12:03
  • PS: to populate a table view you need a parent array containing dictionary instances all with the same keys as in your NSLog output. In the table view method `cellForRowAtIndexpath` get the dictionary for the specific index path from the array and display the values of the keys you need – vadian Aug 29 '15 at 12:03
  • 2
    I'm voting to close this question as off-topic because OP should've read. – The Paramagnetic Croissant Aug 29 '15 at 12:04
  • 1
    (BTW this has nothing to do with Xcode.) – The Paramagnetic Croissant Aug 29 '15 at 12:04
  • 1
    The problem occurs outside of the scope of the code you posted. Somehow you are getting a dictionary in your `myarray` variable. Post the definition of `myarray`, as well as the code that stores a value into it. That's where your actual problem lies. (See my answer below for a detailed explanation of what's going on.) – Duncan C Aug 29 '15 at 13:43

4 Answers4

1

You are getting crash, because you are trying to get index value from dictionary. you have a dictionary actually.

Try

NSString *row1 = myarray[@"date1"];
Pawan Rai
  • 3,434
  • 4
  • 32
  • 42
  • This leads to error "Expected method to read dictionary element not found on object of type 'NSArray *'" – R2D2 Aug 29 '15 at 12:01
  • 1
    @Richard Yes it will, because you are trying to save a dictionary in array, where as you should use a nsdictionary. – Pawan Rai Aug 29 '15 at 12:04
1

As others have said, the variable myarray contains a dictionary.

To explain fully:

In Objective-C, a variable that contains an object actually contains a pointer to that object. Think of it as an entry in your program's rolodex.

The variable has a type, "pointer to array". It points to an object that should be an array.

However, it is possible to lie to the compiler, and have the variable point to something that is not actually an array.

EDIT:

To continue the rolodex analogy, it's as if you have an entry in your rolodex for a plumber, but the phone number (the pointer) is actually the phone number for a roofer. You call the number and start asking the person that answers about plumbing. The roofer doesn't understand what you are talking about, and hangs up. (The conversation crashes.)

The phone number is the pointer, of the wrong type. The pointer of type plumber actually points to an instance of the roofer class, so bad things happen when you start sending plumber messages to the roofer.

Take this code for example:

- (void) typeCasting;
{

  NSDictionary* aDict = 
  {
    @"key1": @"value1",
    @"key2": @"value2",
  }  // -1-
  NSArray *anArray;

  //The compiler throws an error here.
  anArray1 = aDict;  //-2-

  //The compiler allows this due to typecasting.       
  anArray2 = (NSArray *) aDict;   //-3-

  //This code compiles but crashes at runtime.
  NSString *aString = anArray2[0];  //-4-

  //typecast back to dict
  NSDictionary *anotherDict = (NSDictionary *) anArray2; //-5-
}

At the line marked -1- above, we create a dictionary.

At -2- we try to assign our dictionary to a new variable of type NSArray*. The compiler complains, as it should. This is a programming error that the compiler prevents.

At -3-, we commit the same error, but this time we add the (NSDictionary*) typecast, which tells the compiler "Trust me, I know what I'm doing." This is setting us up for runtime crashes later.

At -4- we try to index into anArray2, but it doesn't really contain an array, it contains a dictionary. We crash.

My guess is that somewhere in your code, you have a line like -3- where you cast a dictionary to an array, and set yourself up for your crash. The correct fix is to not do that in the first place. However, you could "band-aid" it after the fact by re-casting your myarray back to a dictionary, as shown in -5- above.

Community
  • 1
  • 1
Duncan C
  • 128,072
  • 22
  • 173
  • 272
  • Correct me if I'm wrong, but everybody who commented or answered on your question explained that you're dealing with a dictionary instead of an array. I even commented that you might have casted the dictionary to an array: the answer above describes exactly the same. Typecasting belongs to the basics of OOP, so we thought you would get it. I thought like that anyway. – Bart Hopster Aug 29 '15 at 20:41
0

What you think is an array is not an array.

The datatype of your myarray might be NSArray or NSMutableArray, but the data that has been assigned to it is not. You can easily see this from your log and exception. The log shows the value of myarray as:

{
date1 = 2000;
date2 = 2010;
reference = 8;
text = "test 4";
}

That is a dictionary. The same is pointed out in the exception log [__NSCFDictionary objectAtIndexedSubscript:]. It clearly states that you're trying to call a method of the NSArray class on an object of type NSDictionary.

The reason this is happening is simple. The compiler will not give you a warning/error when assigning a value to myarray since myarray is being assigned a value during runtime, which results in an exception.

Solution: You can do multiple things. 2 possible solutions are:

  • Change the datatype of myarray to NSDictionary and that will work just fine, and use it as a dictionary.
  • Find out where in your code, is the value being assigned to myarray. Make sure a valid array is being assigned by checking the data during runtime and converting where needed. Simplest but hacky, use allValues while the data is being assigned to myarray. That will assign a valid array to myarray and you wouldn't need to touch any code in owner VC of myarray.
n00bProgrammer
  • 4,261
  • 3
  • 32
  • 60
  • Down voters, please add a comment why you think the answer is wrong. – n00bProgrammer Aug 29 '15 at 11:56
  • I understand this, and have tried many various things to try and convert the array to a dictionary and then retrieve the value from the converted dictionary. Do you have any code on how to turn this in to a dictionary and then access the values from it? – R2D2 Aug 29 '15 at 11:58
  • "Change the datatype of myarray to NSDictionary and that will work just fine, and use it as a dictionary." Yes - this is my problem! Everything I try in order to do this doesn't work. This is exactly what I am trying to do. – R2D2 Aug 29 '15 at 12:32
0

You're dealing with a NSDictionary instead of NSArray, so myarray[0] doesn't work. Use myarray[@"date1"], myarray[@"reference"], ... instead.

Bart Hopster
  • 252
  • 1
  • 4
  • This leads to error "Expected method to read dictionary element not found on object of type 'NSArray *'" – R2D2 Aug 29 '15 at 12:01
  • That's probably because you casted the dictionary to a NSArray. Treat the object as a dictionary and it should work. – Bart Hopster Aug 29 '15 at 13:04