4

I am trying to set up an object to control all of my data so it can set things up in the background to it appears my tableviews load faster than they do now etc.

This is what I am trying to achieve.

enter image description here

I am setting a variable in the NSObject from the secondVC when the tableviewcell is selected like this:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//Access selected cells content (cell.textLabel.text)
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];

    //Parent view logic (sends info back to the correct cell in parent view)
    if (parentViewSelectedIndexPath.section == 0) 
    {
        if (parentViewSelectedIndexPath.row == 0) 
        {
            //Predicates restrict the values that will be returned from the query
            NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K like %@",@"MANUFACTURER",cell.textLabel.text];
            NSArray *filterArray = [myDataArray filteredArrayUsingPredicate:predicate];
            //[[self delegate] setManufactureSearchFields:filterArray withIndexPath:indexPath]; //This is where I pass the value back to the mainview
            //Using Object
            VehicleControllerNSObject *vehicleControllerNSObject = [[VehicleControllerNSObject alloc] init];
            [vehicleControllerNSObject setFirstCell:filterArray];

        }
//etc

At the end there you can see the method that is getting set up in the VechicleControllerNSObject which looks like this.

-(void)setFirstCell:(NSArray *)array{

    manufactureSearchObjectStringFVC = [[array valueForKey:@"MANUFACTURER"] objectAtIndex:0];
    NSLog(@"%@", manufactureSearchObjectStringFVC); // this prints the correct value to the console
}

As you can see this prints the correct output fine.

however I have no idea how to call manufactureSearchObjectStringFVC and pass the value it holds into the uitableviewcell that I would like to pass it in on my firstviewcontroller.

This is what I have for testing atm.

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    VehicleControllerNSObject *vehicleControllerNSObject = [[VehicleControllerNSObject alloc] init];
    manufactureSearchObjectString = vehicleControllerNSObject.manufactureSearchObjectStringFVC;
    NSLog(@"%@", vehicleControllerNSObject.manufactureSearchObjectStringFVC);

}

That nslog prints null..

I have three questions

1, how do I get the correct value into the first valuecontroller.

2, should I be using viewDidAppear like this?.. I think not.. how can I do this better

3, Do you think this is a good way of doing this type of thing, as in the future i would like to use the NSObjectClass to parse info, cache etc all behind the senses leaving the views to just display when the data is ready hopefully helping performance..

Any help would be hugely appreciated as I really want to learn this stuff as i know its important for me to know.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
C.Johns
  • 10,185
  • 20
  • 102
  • 156

2 Answers2

4

Your question is so beautifully and clearly formatted and diagrammed that it seems a shame to ask you to do a search. But here it is:

Search for Sharing Data between View Controllers

You'll find many good discussions about sharing data between view controllers.

Briefly, though, I can tell you why your code isn't working. In your tableView:didSelectRowAtIndexPath: method, you are creating (alloc/init) a new instance of your VehicleControllerNSObject class each time. Then back in your first view controller on viewDidAppear:, again you are creating (alloc/init) a whole new instance each time.

So you have multiple objects coming and going and they have nothing to do with each other. It's a bit like giving some important information to one person at a bus station and then later randomly picking some other person out and trying to retrieve that same information from her.

So one quick idea would be to create just once instance of your VehicleControllerNSObject (just an aside, that's a bit of a strange name for a class since generally all objective-c objects are descendants of NSObject anyway. I'm just going to call that VehicleController for now)

So let's say you wanted a 'sharedInstance' of VehicleController. You could add a class method to VehicleController to give you a way to easily get that one sharedInstance:

+(VehicleController*)sharedInstance {

    static VehicleController *sharedInstance_ = nil;

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{

        sharedInstance_ = [[VehicleController alloc] init];
    });

    return sharedInstance_;
}

So to get that instance in methods in other classes you can just do something like :

VehicleController *sharedController = [VehicleController sharedInstance];
sharedController.someProperty = someValue;

// and then back in your first view controller, similarly:
VehicleController *sharedController = [VehicleController sharedInstance];
id someValue = sharedController.someProperty;

Again, check the search, many people have had good discussions on this. This is just one approach. I hope it at least makes sense why your code wasn't working.

Hope that helps.

Community
  • 1
  • 1
Firoze Lafeer
  • 17,133
  • 4
  • 54
  • 48
  • 1
    Thanks for the kind comment on the format/detail of my question I try hard to ask my questions like this in the hope that it will later help someone who stumbles across looking for an answer to a similar problem and also to hopefully receive great detailed answers such as yourself. thanks very much I understand what you saying and kinda thought that might be the problem but think I confused myself with ARC thinking that it would no not to release the object when it was created.. which now that I think about it is ludicrous :P I'm off to read your link now Thanks a bunch! – C.Johns Nov 10 '11 at 01:32
  • With regards to the code you have here. Is it possible to make the shared instance initialization viewable by the whole class. (i.e. initialize it in the header file of the class so it become public to all the methods of that class?) or is this not possible/bad practice? – C.Johns Nov 10 '11 at 02:51
  • Well, are we talking about the VehicleController class? Instance methods in that class can just refer to 'self', and that would be the one shared instance (if you did everything else correctly). Class methods can simply use [[self class] sharedInstance] – Firoze Lafeer Nov 10 '11 at 02:58
  • jezz I missed the last thing you said.. cool thanks for that. so if i initialize in the .h of a ViewController class then i just use [[self class] sharedInstance]. This is awesome! this has been the only thing holding me back from using NSObjects in the past.. makes so much sense right now :) – C.Johns Nov 10 '11 at 03:13
  • ok, not sure what "initialize in a .h" means. You can't initialize anything in a header file. But post up some code or ask another question if needed. And remember [[self class] sharedInstance] would work only in other class methods of VehicleController. In other classes, you would have to use [VehicleController sharedInstance]. See the examples in my answer. – Firoze Lafeer Nov 10 '11 at 03:18
  • okay cool, thanks again for taking the time to come back and answer these questions! :) – C.Johns Nov 10 '11 at 03:34
1

To answer question 3. No.

I think that the best way to do something like this would be to use Core Data and it's NSManagedObject.

A combination of UITableViewController and NSFetchedResultsController that is feed from a Core Data sqlite backing store, if well set would feed and keep your UITableView updated.

It would be to long to describe all in here. So I will stop there.

If you don't want to go with that there is always the possibility to use a shared pointers to a mutable object or to use a singleton object to communicate information between UIViewController.

Vincent Bernier
  • 8,674
  • 4
  • 35
  • 40
  • okay thats good to know, all be it slightly confusing as I have not researched this approach yet.. It just seems that there are so many different ways to skin this cat that its hard to choose the right thing. I have lots of questions for you.. but I just don't know how to explain them I'm going to go read some more information on this. Thanks heaps for the reply – C.Johns Nov 10 '11 at 01:39