create a global NSMutableArray - nsmutablearray

I have a lot of View Controller and all use the same Class (ViewController).
In ViewController.m I have this code:
- (void)viewDidLoad
{
[super viewDidLoad];
pedidoNomeArray = [[NSMutableArray alloc] init];
pedidoValorArray = [[NSMutableArray alloc] init];
}
and when I go to View Controller number 2 my array pedidoNomeArray and pedidoValorArray are null.
What I have to do to use the same array in all my View Controllers?
thanks

One reason could be that you are not using ARC. In this case you assign the newly initialized array directly to an ivar, i.e. without using a setter. In this case, the array is not retained, and released as soon as your app enters the run loop. So, if you are not using ARC, use pedidoNomeArray = [[[NSMutableArray alloc] init] retain]; instead. But you should really use ARC since it avoids most of the common memory management problems.
EDIT (due to you comment):
Now it seems to me that what you need is a data model according to the MVC software architecture pattern. Your data are stored in an independent object, and both of your view controllers have a reference to this object. Your data model, which contains your "global array" could be instantiated e.g. in your application delegate or your root view controller, this is debatable, examples and discussion see here. I hope this helps.

Related

subclass NSWindowController Core Data

I have a newb question, which I have tried unsuccessfully to find answers for on the web. The task is simple: I want to create a core data document-based app but alter the values in some label objects. Using interface builder, I can build the core data model and populate it, using an array controller, table, etc. all without writing any code. So far so good. My test example is to build a core data model with Box entities that have length and width attributes. I would like a label to display the area, i.e. length*width for any geometrically challenged :).
So after browsing around, I've decided I need to create an NSWindowController subclass and use that to update the label when a box in the table is selected. Have attempted this, but have failed. Before I even hook up the label to the window controller, I have a problem. Following the template comments, I added this to Document.m:
- (void)makeWindowControllers
{
NSLog(#"Adding custom Window Controller");
MyWindowController* myWindowController = [[MyWindowController alloc] init];
[self addWindowController:myWindowController];
}
Also added this to the template MyWindowController.m:
- (id)init
{
self = [super initWithWindowNibName:#"MyWindowController"];
return self;
}
The window controller has its own NIB file from Interface builder where I put the table and label etc. The file owner is set to MyWindowController. Probably forgetting other things, but that's what I remember for now.
The log message appears at startup, but then I get an exception "this class is not key value coding-compliant for the key managedObjectContext" before the window appears. I'm guessing that I don't have the window controller hooked up to the document class properly? My other thought is that the array controller is in the window controller nib, not the document nib, so maybe it's looking in the wrong place for the managedObjectContext?
I would try a different approach: Add area to your Box entity as a read-only attribute. Auto-create a Box class with Xcode ("Create NSManagedObject Subclass" menu item in the "Editor" menu when viewing the data model), then add this to Box.h
#property (weak, readonly) NSString * area;
and this to Box.m
- (NSNumber *)area
{
return [NSNumber numberWithDouble:([[self length] doubleValue] - [[self width] doubleValue])];
}
+ (NSSet *)keyPathsForValuesAffectingArea
{
return [NSSet setWithObjects:#"length", #"width", nil];
}
If you do this you can just bind area to a label value like you do for the other Box properties. No need to subclass NSWindowController or watch for changes.

To Use NavigationViewController or NOT

I am creating an application which displays map using MKMapView control. I have a button on the map that takes me to different view (information view) using the following code:
InfoViewController *infoViewController = [[InfoViewController alloc] initWithJogInfo:jogInfo];
self.view = infoViewController.view;
Now after going to the information view I want to go back again to the main view which displays the map without having to loose anything. Is NagivationControlller my best option to use in this scenario?
Try this,
InfoViewController *infoViewController = [[InfoViewController alloc] initWithJogInfo:jogInfo];
[self.navigationController pushViewController:infoViewController animated:YES];
[infoViewController release];
once you push viewController back button is available to come back to rootViewController.

Getting UITabBarController to work with Core Data

I've been reading this thread on Stackoverflow and have been trying to replicate the solution with no success in my own project.
My project has 4 tabs. In my app delegate I do this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
Page1 *page1 = (Page1 *)[navController topViewController];
Page2 *page2 = (Page2 *)[navController topViewController];
Page3 *page3 = (Page3 *)[navController topViewController];
Page4 *page4 = (Page4 *)[navController topViewController];
page1.managedObjectContext = self.managedObjectContext;
page2.managedObjectContext = self.managedObjectContext;
page3.managedObjectContext = self.managedObjectContext;
page4.managedObjectContext = self.managedObjectContext;
[self.window makeKeyAndVisible];
return YES;
}
In the originating thread it says I need to create a IBOutlet to each navController for each tab I want to use Core data on.
Whilst you can assign multiple delegates for the UINavigationController the same is not true for the outlets, you can only ever supply ONE outlet for the navController.
I can get Page1 to work, but the other pages simply crash; because of the lack of an IBOutlet.
Do I really need X IBOutlets for Y Tabs or can I do it another way?
Another issue is that the originating thread the accepted answer is:
Ideally you want to pass either the
NSManagedObjectContext,
NSFetchedResultsController or the
relevant NSManagedObject "down" into
the UIViewController.
But there is no code or example of how to do this.
Ideally, I do not want to use a singelton or use the app delegate all over the place.
Any confirmation and clarification would be great.
Thanks.
Your immediate problem has nothing to do with Core Data. You are assigning the same navigation controller to each tab when you need a separate navigation controller for each tab otherwise the navigation controller's hierarchy of views will get scrambled every time you change tabs.
The pattern recommended in the question you linked to is called "dependency injection" and it is the one that Apple recommends in most cases. However, in the case of tabbars or any other complex view/view-controller hierarchy, dependency injection can get to complicated. It's a particular issue with tabbars because you don't usually load all tab view/view-controllers when the app starts but wait until each tab is selected before loading its elements.
Instead, you can use an alternative pattern that exploits the UIApplication objects singleton status. Since there is only one application object, there is only one application delegate object. That means that anywhere in the app you can make a call like this:
(MyApplicationDelegate *) appDelegate=(MyApplicationDelegate *)[[UIApplication sharedApplication] delegate];
... and always get the same application object. Then, if you have the managed object context defined as a property of the app delegate you can get the context just by:
theManagedObjectContext=appDelegate.managedObjectContext
Add these two lines to every view controller and you can always be sure of getting the app delegate's managed object context.

NSFetchRequest data into a view?

I am just getting started with the CoreData API and am following a few tutorials. I get the basics of storing and retrieving objects, but am having trouble connecting all the pieces in terms of MVC.
I have a CustomView into which I draw some stuff with CoreAnimation, including some text layers that will get their strings from an NSManagedObject. I started with a basic CoreData application template so the managedObjectContext etc are declared in the appDelegate, and I'm just not sure how I should be getting data from the CoreData stack into the view. By the way, this is all in code, not interface builder.
So my question is, if I want to build my app in a pure MVC way, how should I go about getting data from the stack into the view? How should I give my view access to the initialized NSManagedObjectContext, for example?
I have been reading Cocoa Design Patterns but am a bit of a dunce when it comes to MVC. I know its a pretty general question, but if someone can just say, "set the delegate, grab a pointer..." whatever it is, that would be great!
Thanks in advance!
So I did some more poking around and it seems the easiest way to do this is to get a pointer to the AppDelegate and then a pointer to the managedObjectContext. From there, execute a fetch request and put it into your view!
In a good tutorial Björn Sållarp does it this way:
From the app delegate he creates the rootViewController and sends it the context with:
RootViewController *rootViewController = [[RootViewController alloc] initWithStyle:UITableViewStylePlain];
rootViewController.managedObjectContext = context;
rootViewController.entityName = #"Counties";
In the rootViewController's h file you declare:
NSManagedObjectContext *managedObjectContext;
Create its property:
#property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
and in m you
#synthesize managedObjectContext;
Then its there for your use.

FBConnect - template not using my template bundle

I registered a template bundle for my app, one that only uses *actor*, so I brought it up like this:
FBFeedDialog* dialog = [[[FBFeedDialog alloc] init] autorelease];
dialog.delegate = self;
dialog.templateBundleId = 12345;
[dialog show];
(using my bundle id, of course)
But all I get when the dialog comes up is "Do you want to publish this story to your Profile?". The "story" doesn't show up in the dialog, and if I click Publish I end up with a blank story in my feed.
Then I tried registering another one which a) has only a one-line story, to make things simpler (the first one had everything) and b) uses a custom key.
FBFeedDialog* dialog = [[[FBFeedDialog alloc] init] autorelease];
dialog.templateBundleId = 12345;
dialog.templateData = #"{\"flavor\": \"chocolate chip\"}";
[dialog show];
Same result, blank story. I've done a lot of google searching and can't find anyone else with this problem, so I must be doing something incredibly silly. Can anyone advise, please?
I fixed it, but I don't quite understand the fix (I'm new to Obj-C as well as iPhone).
I have an ivar called session, which stores the FBConnect session, for which I had an #property and #synthesize as usual. I removed both of those and explicitly retained the session when it was allocated, instead of relying on the property to do it, and it started working. I don't see how these are functionally different, but in comparing my code to the sample, which worked, I noticed this difference and tried it. The release is in the dealloc method, which is where it was all along.
I would love an explanation if anyone can give one!

Resources