Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
300 views
in Technique[技术] by (71.8m points)

iphone - Passing array between view controllers?

I really need some more help!

I am trying to pass an array from one view controller to another. I think the latter being a 'child' view controller?

My code is as follows:

MainViewController.h:

#import <UIKit/UIKit.h>
#import <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVFoundation.h>

@interface HelloWorldIOS4ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate, AVAudioPlayerDelegate> {
    NSMutableArray  *countProductCode;
    UIPopoverController *detailViewPopover;
}

@property (nonatomic, retain) NSMutableArray  *countProductCode;

@property (nonatomic, retain) UIPopoverController *detailViewPopover;

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;
...
@end

MainViewController.m

#import "HelloWorldIOS4ViewController.h"
#import "JSON.h"
#import "PopoverContentViewController.h"

@implementation HelloWorldIOS4ViewController

@synthesize detailViewPopover;
@synthesize countProductCode;

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 
{
    NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

    NSDictionary *results = [jsonString JSONValue];
    NSLog(@"RETURN: %@", results);

    [countProductCode removeAllObjects];

    NSArray *products = [results objectForKey:@"items"];

    for (NSDictionary *row in products)
    {
        NSString *code = [row objectForKey:@"ic"];
        [countProductCode addObject:code];
    }

    PopoverContentViewController.countProductCodes = countProductCode;
}       

PopoverViewController.h:

@interface PopoverContentViewController : UITableViewController {
    NSMutableArray  *countProductCodes;
}
@property (nonatomic, retain) NSMutableArray  *countProductCodes;
@end

PopoverViewController.m:

#import "PopoverContentViewController.h"
#import "HelloWorldIOS4ViewController.h"

@implementation PopoverContentViewController

@synthesize countProductCodes;
...

I have cut a lot out, but I know from a load of NSLog's dotted around that I get the data back etc, but I cannot pass the array countProductCode to the PopoverViewController's countProductCodes array.

I keep getting

"Accessing unknown 'setCountProductCodes:' class method"

errors.

This may be something really silly that I'm doing but it's driving me crazy!

Can anyone help please?

Thanks James

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Dear James, I think you would like to have a closer look at the Model-View-Controller paradigm. In your app you are trying to implement some kind of a "super class". Let me explain what that means:

In your MainViewController class which is clearly a controller there is also some part of the model implemented. This is a bad idea, but a very common one to make in the beginning. Maybe I misunderstood your design, but here is how I would implement it:

The Model I would implement a proper model object, which could be in your case as easy as a custom NSObject subclass with a NSMutableArray as a property. In addition this model would have the methods for retrieving data off the internet implemented. That is right: do the networking in the model. You would have to have methods like - (void) refreshProductCode that you would call from your controller. If you want to get really fancy, use an NSOperation to encapsulate the download (then you would use the a synchronous variant of NSURLConnection, because the operation itself is already executed asynchronously) The nice thing would be then if your parsing of the JSON string takes longer, also this is performed in the background and your UI will stay responsive.

So now the model is downloading your stuff - great, but how do I know when it is done? Well you would post a Notification from the model once it is done. What if the download fails? You guessed it right: post a notification that it failed.

The Controller The controller which needs to display data from the model would first to get the model object. In this case the model object is a property on your AppController. The controller then has a property for this model object and retains it, so that the model object does not go away while the controller lives. The controller then also registers for notifications of the model. So how would a typical download work then?

  1. Get an instance of the model object
  2. call -(void) refreshProductCode on the model object
  3. display network activity spinner in status bar and wait for notifications
  4. when the notification came in, on success refresh the UI and on failure restart download or display a note to the user. Also disable the network activity spinner.

How do you shuffle data between view controllers? View controllers should operate a bit like the mafia: every view controller is working on a need-to-know basis. For example if you want a view controller to display the details of your product, you would not pass the model with all your products to the controller. Instead you would have an instance variable on the detail view controller holding only one produce model object, which has all the information like description text, photo etc. The cool thing then is if you ever want to display product information again in you app, you can reuse that view controller, as all it needs is a product model object to do its job.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...