Alternatives to NSMutableDictionary? - iphone

I have 3 NSMutableDictionaries that hold data for 3 separate UITableViews. When a value is checked from one of the UITableViews, I want to hold that value so depending on the different values that are checked from the different tables, I can generate an answer on the next page. I thought maybe I could create a new NSMutableDictionary that has all the possible selections, and then when a user hits the checkbox, to tell my newNSMutableDictionary that that value has been selected. But I don't think it works that way since it's a key-value-pairing. I was wondering if there were alternatives to this, or if someone had a good way of holding this information? Thanks.

Instead of doing this, you can try having one NSMutableArray of the selected NSIndexPath objects.
This way, you'd have a pretty lightweight memory footprint (lazy loading) and if you needed to grab the actual cell's value, you can ask the UITableView with -tableView:cellForRowAtIndexPath:
Or, even better, have one NSMutableDictionary with one the keys being the tag of the specific tableview wrapped in an NSNumber and the value being an NSMutableArray of selected index paths.
To retrieve the selected index paths would be as simple as this:
NSArray *indexPaths = [selectedDict objectForKey:[NSNumber numberWithInt:tableView.tag]];
for(NSIndexPath *p in indexPaths) {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:p];
//do something with cell...
}

why not store all possible selections in a NSDictionary, initialise it with the all the selections a user can make. When the user makes a selection add that item to a "selectedItems" NSMutableDictionary. This way your NSMutableDictionary (that contains selections) will only ever have the selected items in it, you can then add and remove from this dictionary without needing to mutate the non-mutable NSDictionary that contains the selections that a user can make..?

I'm not sure if I've understood your problem right.
But, if your data has the "shape" of a tree you might consider to save the information in this way.
You can put a Dictionary inside your Dictionary
You can put your data in CoreData and use NSTreeController

Related

UISearch bar in two NSMutables arrays

I see item UISearchBar search two arrays and very much items and not found solution, the problem its similar, have two NSMutablesArrays "subdetail" and "sublista" its show in Cell cell.textLabel and cell.detailTextLabel.
I try UISearchbar but i tray with NSPredicate and not run, try with NSRange and have more errors, i am desperate.PLEASE help me, any comments agree.
This its my code in Search:
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
NSMutableDictionary *playas = [NSMutableDictionary dictionaryWithObjectsAndKeys:sublista, #"nombre", subdetail, #"localidad", nil];
[alldata addObject:playas];
for(NSDictionary *playas in alldata){
NSString *nombre = [playas objectForKey:#"nombre"];
NSRange nombreRange = [[nombre lowercaseString] rangeOfString:[searchText lowercaseString]];
if(nombreRange.location != NSNotFound)
[filteredList addObject:playas];
}
}
Add rest of code .m and .h
https://dl.dropboxusercontent.com/u/6217319/BuscarViewController.h
https://dl.dropboxusercontent.com/u/6217319/BuscarViewController.m
Thanks in advance.
BEST REGARDS
Your code has a lot of issues with it. I don't know which ones are actually breaking it, but any of these issues could be causing severe problems.
First, the code sample you provided doesn't provide declarations for a lot of hte objects you're referencing. No way this could possibly compile as given. If these are properties of the view controller instance, you need to use the accessor methods -- self.alldata or [self alldata], whichever you prefer.
Second, it looks like you're just adding to these properties. If you never reset their contents, every time this method is called, you're going to increase the size of your data set -- looking at your code, possibly recursively.
Third, you try to merge the two datasets together, and then try to search through only one of them. Either don't merge, or search through both seperately and then merge the results. As it is, what you're doing won't work.
Fourth, your table view should really only be displaying one type of data, so you shouldn't need to merge.
Edit:
Based on the code samples you've provided, your entire VC is going to need restructuring. Given how much of your code is written in what appears to be spanish, I'm doing a bit of guesswork at what you're actually doing.
First off, assuming you're using a modern version of xcode, get rid of the #synthesize in the .m file (it's no longer needed anymore). That will cause every single place you're using the actual ivar instead of a proper getter to turn into an error, so you can fix them quickly. iVars will by default use a prefixed underscore of their property name, so you can still access them if you have to -- but only by explicitly accessing the ivar instead of the property.
Second, you should restructure how you handle the data. I don't know where you get your data, but it looks like the various objects are fairly consistent. You should go ahead and either create a new class to hold all the data, or just put them all into a single dictionary. At that point, the 'alldata' property should, in fact, be an array of all valid data. What you should do is then have a filtered list of data (filteredData would be a good name), and you place whatever data matches the search criteria in there. Just remember to either reload the table or update it appropriately as items move into and out of the filtered list.

Does the UITableView function visibleCells return custom cell data?

I have a number of custom cell objects (subclasses of UITableViewCell) with a couple of values in them to allow for user interaction within individual cells (like steppers or something). These values are stored within the custom cell class, since calling up to the owner of the table view seemed like a bad idea at the time.
I know of the function (NSArray *) visibleCells. Will that allow me to access the data within the cell objects?
If not, how?
I'm assuming that I can use the built-in functions of the UITableView to pull returned UITableViewCells, but is that sufficent when I'm talking about a subclass of that called, say CustomizerCell?
The function:
- (NSArray *)indexPathsForVisibleRows
Answers an array of index paths. Those index paths can be used the same way your cellForRowAtIndexPath uses the passed index path to access your model.
MyObject *myCustomDataSupportingACell = [myDatasourceArray objectAtIndex:indexPath.row];

Populating UITableView with Dictionary Data

My Situation:
I have an NSDictionary object. Keyed by NSNumber. Values are custom objects.
I want to put dictionary values into a UITableView. As far as I can tell, UITableView requires that its source collection be indexed so when cellForRowAtIndexPath is called, you can use the indexPath to look up the value.
Problem is that when didSelectRowAtIndexPath is called, I want to look up the object from the dictionary, but I don't have the key. All I have is the indexPath.row.
My solution:
I create an array of keys. I use the index of the array to get the key, and then use the key to get the object out of the dictionary.
My problem:
This seems kind of sloppy especially since this is a routine task (populating the UITableView and then responding when someone touches a cell). Is this the way it's designed to work or is there a better way?
The problem is that dictionaries don't have an order, while a table view does. The answers to this question should give you some ideas for alternative ways of handling this.
As mentioned in another answer, an NSDictionary's keys are not ordered, therefore you are not guaranteed to get the rows in a particular order. That said, it is quite easy to use a dictionary for use with a UITableView.
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// tableview cell setup
NSArray* keys = [self.data allKeys];
cell.textLabel.text = [self.data objectForKey:[keys objectAtIndex:indexPath.row]];
return cell;
}
If you need the list to be ordered according to how you entered them into the NSDictionary, Matt Gallagher from Cocoa With Love offers an elegant solution with his take on OrderedDictionary. You can read about it here.

A Question about Assign Properties

Edit 2: What I previously planned was probably a bad idea and I now changed my design: My UITableViewController has an array with all the values of my UITextFields and I am using delegation to update the values in the array. (If a value in one UITableViewCell changes, I send a message with the new value and the index of the cell).
Original Question
I would like to create a UITableViewCell subclass. To access my cells, I would like to have an NSMutableArray in my UITableViewController with all the cells. Whenever I create a new cell in - tableView:cellForRowAtIndexPath: I would add it to the array. The cells should however know about this array. I would declare a property like this for the UITableViewCell:
#property (nonatomic, assign) NSMutableArray *cellsArray;
Whenever I create a new cell, I would set its cellsArray to my array.
My (probably simple) question is: Is it correct that cellsArray will hold a pointer to the array in the UITableViewController and when I add stuff to the array of the UITableViewController, the cells will know this too, i.e. can access it?
Edit: The UITableViewCells contain UITextFields. I used to rely on the -cellForRowAtIndexPath: method and the visibleCells array, however when the cells moved out of view, the content of their UITextFields would also be lost. I then decided to store the cells in an array. When the user taps save, I iterate through the array and store the values. Also, I would like to automatically update the enabled property of the save button, depending on whether all cells contain something - for this I need all cells, too.
The cells should know about the other cells so that they can select the next cell when the return/next key on the keyboard is pressed.
If there are better approaches to this, I am glad to hear about them!
Not a direct answer of your question, but this sounds like a very bad design. Why should one cell need to know about its siblings? Any event/change that occurs in one cell and has an effect on the other cells should be handled by the table view controller. The single cells should be separate entities that should have no need to know about the state of each other.
Secondly, there is no need to introduce another array to manage the table cells. The table view already has a property visibleCells that you can access from the table view controller. And should never have to interact with invisible cells anyway because those are managed by the table view and its reuse facility.
I believe the answer is Yes.
My understanding of assign is that you can assign a value to such a variable and the retain count for the original object is not incremented. Similarly you need not release the variable in the object's dealloc method. You may run the risk, however, that the original array goes away and then cellsArray is pointing at something that is no longer there.
I use assign when I want to pass a reference to an object to another object (e.g. a view controller that is going to display or otherwise manipulate the object). And in the latter object, I do not release it's pointer to the object.
You also see assign used with properties that are id's, like
#property (nonatomic, assign) id<SomeProtocol> _myDelegate;
All that being said, with the exception of the id case, often I feel "safer" using retain for the property and being sure to release in dealloc. :-)
Anyway, I think that's the crux of the difference.

Display NSArray values that are stored in an NSDictionary

I'm trying to store an NSArray object with a simple key (1,2,3 etc.) inside an NSDictionary. I'm pretty sure thats worked, but I'm not sure how to display the array data thats stored in there, I've got the following working (displaying a single array of data)
The test app i'm working on is a simple dictionary. Definition is the class i've got for words and their definitions, and words is an array which has two values - word and definition
Definition *words = (Definition *)[appDelegate.words objectAtIndex:indexPath.row];
It then shows the data in a table view:
[cell.textLabel setText:words.name];
[cell.detailTextLabel setText: words.description];
Not quite sure what you're asking here. You create a Definition instance, so what properties does it have? If you have NSStrings name and description in it, then that code should work fine, but I think you're trying to do something different.
You access information in a NSDictionary by calling objectForKey: or valueForKey:.
You can also store information in the object. If you created your Definition to hold two strings--name and description, you could bypass the NSDictionary all together.
Could you post your Description.h so we can see what's going on?