views:

840

answers:

3

I have some code which needs to access a NSArray to work. I have a NSArray which I am using with core data and will have data in it. But i am unsure how to make it access the NSArray. I can't just simply declare it in the Header file like this: NSArray *objectArray; because it does not know how or which NSArray to Access. How exactly would I access the NSArray I am using with core data?

Some Code To Help. Header File.

#import <Cocoa/Cocoa.h>


@interface MyOutlineView : NSOutlineView {
    NSArrayController* objectArray;
}

@end

Implementation File.

#import "MyOutlineView.h"

@implementation MyOutlineView

- (void) outlineView: (NSOutlineView *) aView
     willDisplayCell: (id) aCell
      forTableColumn: (NSTableColumn *)aColumn
                item: (id) anItem
{
    id rootObj = anItem;
    unsigned row = [aView rowForItem:anItem];

    [aCell setDrawsBackground: YES];

    while ([aView levelForRow:row] != 0) {
     row --;
     rootObj = [aView itemAtRow:row];
    }

    // The colours here are foul and ugly.  Use something else, for
    // God's sake!
    if( [objectArray indexOfObject:rootObj] % 2 )
     [aCell setBackgroundColor: [NSColor yellowColor]];
    else
     [aCell setBackgroundColor: [NSColor blueColor]];
}

@end
A: 

I've made a test app with IBOutlet connected to NSArrayController from Xib. In this test I have:

  • started from Core Data application template;
  • created Entity in data model with two attributes (string, int);

in Xib:

  • Array Controller with managed object context, connected to Test_AppDelegate.managedObjectContext;
  • TableView with cols connected to Array Controller's first and second attribute of arrangedObjects;
  • Add and Remove buttons, connected to Array Controller's add: and remove: actions;
  • Button "Show Count" and Label; -

in code (Test_AppDelegate.*):

  • IBOutlet NSArrayController *ac; (connected in Xib from Test_AppDelegate.ac to Array Controller);
  • IBOutlet NSTextField *nLabel; (connected in Xib to Label);
  • (IBAction)showNum:(id)sender; (connected from "Show Count" button);
  • code in action showNum: [nLabel setIntValue:[[ac arrangedObjects] count]];

I'm able to:

  • Add/Remove objects to table view and controlled array;
  • Access NSArrayController from code to get arrangedObjects array.

So binding IBOutlet from code to Xib's Array Controller and accessing its arrangedObjects should work.

Anton
I've Tried Using an IBOutlet to declare objectArray and link it to the NSArrayController. But I get an error saying 'Invalid Operands to binary %' on the line ' if( [objectArray indexOfObject:rootObj] % 2 ) ' because it is looking for an array not an array controller. How would I fix this? I have also updated the first post with all the code I am using.
Joshua
I also read from where i got the code saying that I need to create a Selector. This is what they said, Assume self responds to a selector -objectArray which returns an array of the top-level objects displayed in the outline view, and in the right order.
Joshua
There should be clear understanding that NSArrayController is a controller of array of objects but not an array itself. So to access objects from this controller you should use arrangedObjects property which 'Returns an array containing the receiver’s content objects arranged using arrangeObjects:' (from Apple documentation). These objects are arranged in compliance with sorter and filters of Array Controller and represented as a set of resulting managed objects (NSManagedObject). Each object contains values described in data model which can be accessed by keys with valueForKey: method.
Anton
So, in your case, [objectArray arrangedObjects] will return you an NSArray of all your objects. These objects will have NSManagedObject type (or inherited from it) and attributes can be accessed by [obj valueForKey:@"attributeNameFromDataModel"]. I'm not sure if anItem from your code returns correct type of object (NSManagedObject) and it can be used as indexOfObject: argument but at least you can get a whole set of objects from method I'd described and do your own search.
Anton
So what code do I need to change or add to the code in the first post?
Joshua
To access objects you can use: `NSArray *objList = [objectArray arrangedObjects]; for (NSManagedObject *obj in objList) { NSNumber *attr1 = [obj valueForKey:@"attr1"]; <your logic>; }`. As I said I'm not sure if rootObj from your code is suitable for indexOfObject: function and I don't know the model of your objects but with this cycle you can access all the objects you have in your array and do your logic: finding item you want and making divisibility check on its value.
Anton
Thanks, Where in the code would I put `NSArray *objList = [objectArray arrangedObjects]; for (NSManagedObject *obj in objList) { NSNumber *attr1 = [obj valueForKey:@"attr1"]; <your logic>; }' ?
Joshua
Where would I put it?
Joshua
Your 'if' code accesses the array. The code I gave you do the same but in correct way assuming that objectArray is NSArrayController outlet, bounded from Nib. So you should use this approach to replace your `if( [objectArray indexOfObject:rootObj] % 2 )...`
Anton
Would your code still find/get the root object?
Joshua
Also, I pasted the code in and I got multiple errors and warnings. Here's a picture of what happened: http://snapplr.com/jvw9
Joshua
For one thing '<your logic>' isn't valid Objective-C code.
Abizern
What should I replace '<your logic>' with?
Joshua
A: 

http://stackoverflow.com/questions/431797/programmatically-update-an-attribute-in-core-data

Walker Argendeli
I don't understand how that helps.
Joshua
Well first of all, your qestion was very confusing. I'm honestly not sure what you were asking. I honed in on your sentence "How exactly would I access the NSArray I am using with core data?"This shows you how to access an attribute using core data. It doesn't show and NSArray, but it shows accessing *something* from core data. And seeing that you're offering a bounty, it means you haven't gotten an answer for your question. I'm not sure what you were saying, so I posted something that *might* have helped.
Walker Argendeli
A: 

I might not be getting this - but can't you just create an initWithArray method?

Grouchal
What was wrong with this as an answer?
Grouchal
Could you give me an example?
Joshua
Where do you create your MyOulineView - do you do it in code? If so then instead of using init override init and add your NSArray to the class.
Grouchal
No I created MyOutlineView in interface builder. Could you give some example code and what I need to add to my code?
Joshua