views:

119

answers:

1

I'm having success when I use this code to get a string from an array of file names called "fileList":

cell.timeBeganLabel.text = [[[self.fileList objectAtIndex:[indexPath row]] lastPathComponent] stringByDeletingPathExtension];

so I expected the same code to generate the same string as a key for me in this:

NSDictionary *stats = [thisRecordingsStats objectForKey:[[[self.fileList objectAtIndex:[indexPath row]] lastPathComponent] stringByDeletingPathExtension]];
  cell.durationLabel.text = [stats objectForKey:@"duration"];

or this:

NSDictionary *stats = [thisRecordingsStats objectForKey:@"%@",[[[self.fileList objectAtIndex:[indexPath row]] lastPathComponent] stringByDeletingPathExtension]];

Both build without error, and the log shows my data is there: but I'm getting a blank UILabel.
Have I not written the dynamic key generator correctly?

A: 

I'm having success when I use this code to get a string from an array of file names called "fileList":

cell.timeBeganLabel.text = [[[self.fileList objectAtIndex:[indexPath row]] lastPathComponent] stringByDeletingPathExtension];

So, the result of that message expression is your key, right?

That is to say, the keys in your dictionary are filenames without extensions?

so I expected the same code to generate the same string as a key for me in this:

NSDictionary *stats = [thisRecordingsStats objectForKey:[[[self.fileList objectAtIndex:[indexPath row]] lastPathComponent] stringByDeletingPathExtension]];
cell.durationLabel.text = [stats objectForKey:@"duration"];
  1. You compute the filename without extension as before.
  2. You look up the object for this string in the thisRecordingsStats dictionary, thus obtaining another dictionary, with which you initialize the stats variable.
  3. You look up the object for the “duration” key in the stats dictionary, and set the durationLabel's text to this object.

or this:

NSDictionary *stats = [thisRecordingsStats objectForKey:@"%@",[[[self.fileList objectAtIndex:[indexPath row]] lastPathComponent] stringByDeletingPathExtension]];

Adding the @"%@", part doesn't make sense, since objectForKey: doesn't take a format string. Compare the documentation for NSString's stringWithFormat: method to the documentation for NSDictionary's objectForKey: method.

The code “works” because what you have passed as the argument to objectForKey: is a comma expression. C's comma operator evaluates both sides and evaluates to the right-hand side. However, in this case as in most others, it adds nothing. For reasons like this, the comma operator is rarely used and even more rarely used on purpose.

Cut the @"%@", part out.

Back to the problem:

Both build without error, and the log shows my data is there: but I'm getting a blank UILabel.

Well, you say the key you're generating from the string in your fileList array shows up in the UILabel, so the problem is one of these:

  • thisRecordingStats is nil.
  • thisRecordingStats does not contain an object for the key you generated from the string in self.fileList.
  • thisRecordingStats does contain an object for the key you generated from the string in self.fileList, and it is a dictionary, but it does not contain a value for the key “duration”.
  • thisRecordingStats does contain an object for the key you generated from the string in self.fileList, and it is a dictionary, and it contains a value for the key “duration”, but that value is an empty (zero-length) string.

You should also check the Debugger Console for messages that suggest other problems. For example, a “does not respond to selector” message may be because thisRecordingStats contains an object for the key you generated from the string in self.fileList, but it is not a dictionary.

Finally, I suggest constructing one or more model object classes instead of nesting dictionaries like this. It tends to make the code much easier to read and to debug. In particular, the dictionaries that ostensibly have objects for the key “duration” should be model objects.

Peter Hosey
wow! thanks for your generous response. Aside from creating a model object, might you suggest a way to get the content of the objectAtIndex:1 of the inner array out of the outer array logging as such: thisRecordingsStats is { "5:45:02 PM, April 26" = ( "/Users/.../Documents/5:45:02 PM, April 26.aif", "00:04",etc. My current best guess is: NSArray *stats = [thisRecordingsStats objectForKey:key]; cell.durationLabel.text = [stats objectAtIndex:0]; which also returns blankness.
Brian
I don't see an inner array. The dictionary contains an array as its values, but the array contains strings (at least so far as you show in that excerpt). Remember that arrays in Cocoa are strictly serial, not associative; arrays are not dictionaries.
Peter Hosey