tried to change the NSArrayController selectIndex programmatically, won't work - xcode

I have a question regarding the cocoa binding.
I have a xib file, inside this xib file (named AddInformation.xib), I have added a array controller. I have bound the array to one of my NSMutableArray.
I have also set an IBOutlet for this array controller so that I can manipulate the selection of the array controller
#property (weak) IBOutlet NSArrayController *arrayController;
so, somethere in the code, when I called:
myViewController = [[NSViewController alloc] initWithNibName:#"AddInformation" bundle:nil];
BOOL b = [arrayController setSelectionIndex: 2]; // b is returned as NO
it doesn't work, it always return the first object in the array, even thought I changed the selectionindex to 2 (I have more than 10 objects in the array)
am I missing something?

Related

How can I bind to NSTableColumn's headerTitle?

I would like to bind NSTableColumn's headerTitle property to an NSMutableArray in my model layer (via an NSArrayController).
Basically I want to have an array where I can change values and have the table column header titles update. Is that reasonable?
However, the headerTitle binding wants an single NSString and I'm not sure how to connect my model object to this binding via my NSArrayController. Google does not give many hits for this problem.
My model layer consists of two class (both of which are appropriately KVC compliant). The first is a model which represents a single column title, it has one property title,
// A model class representing the column title of single NSTableColumn
#interface ColumnTitle : NSObject
#property NSString *title;
+ (ColumnTitle*) columnTitleWithTitle:(NSString*) aString;
#end
The second a model object which represents an ordered group of ColumnTitle objects,
// Class representing an order collection of model items
#interface TableColumnTitles : NSObject
#property NSMutableArray* columnTitles; // an array of ColumnTitle objects
// These are the KVC array accessors
-(void) insertObject:(ColumnTitle*)columnTitle inColumnTitlesAtIndex:(NSUInteger)index;
- (void)removeObjectFromColumnTitlesAtIndex:(NSUInteger)index;
- (void)replaceObjectInColumnTitlesAtIndex:(NSUInteger)index withObject:(ColumnTitle*)columnTitle;
#end
Note that TableColumnTitles object implements the above array accessors which are required for the bindings. Any suggestions?
Haven't tried that before but what you're actually asking for is using KVC for array indexes. A quick google didn't turn up anything on that issue except some results that indicate it's not (yet) possible (check this)
The easiest work-around I could come up with would be to simply add dedicated properties for the array indexes.. not nice but does the job.
So for a NSMutableArray called myArray and contains objects with title properties of type NSString you'd do something like:
#property (nonatomic, readonly, getter = columnOneGetter) NSString *columnOneString;
(NSString*) columnOneGetter
{
return myArray[0].title;
}
Always assuming of course their number is known in advance and we're not talking 200 columns :-)
I think this may/may not be what you're after, but quick google search landed me here:
http://pinkstone.co.uk/how-to-add-touch-events-to-a-uitableviewfooter-or-header/
edit: i realize this is for mac (not ios) but should be pretty easy to translate if it actually helps.

How do I change values of another UITableViewController from a different UITableViewController, everything on the same view?

In a View I have this structure
vista1 UIView -> tabla1 UITableView -> tabla1_controller UITableViewController
vista2 UIView -> tabla2 UITableView -> tabla2_controller UITableViewController
I use views because depending of the orientation I move around the views.
Everything works fine, each tableviewcontroller gets data from sqlite and show the custom cells.
I want to add a behavior, when the user selects a cell in the second table, I want to change the content of the first table.
The first tableView gets information from a NSArray, how do I change
So how can I make this happen?
this is the second tableviewcontroller
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
/* I dunno how to reference the nsarray of the first table here */
first_table_array = ....
[tabla1 reloadData];
}
In this case is with two tableviewcontroller, but the real cuestion is,
How can I execute functions / change variables of another tableviewcontroller from one viewcontroller?
For example, in the tabla2_controller (UITableViewController) how can I execute [tabla1_controller reload] when the user clicks on a row of table2,
if both tables are in each own view and both views showed at the same time?
In tabla2_controller, create a variable like below
in .h file
#property (nonatomic, retain) UITableViewController *table1Ref;
in .m file
#synthesize table1Ref;
Then, when you create tabla2_controller, set tabla1_controller as value for this variable like below.
tabla2_controller *t2c = [[UITableViewController alloc] init];
t2c.table1Ref = t1c; //t1c is tabla1_controller
Now, in didSelectRowAtIndexPath of tabla2_controller, do the following.
tabla1_controller *t1c = self.table1Ref;
[t1c.tableView reloadData];

analyze and memory alerts in xcode

I ran 'analyze" in xcode on a current iOS project to try to track down a freeze issue and there are a number of memory alerts that I don't understand (screenshot of one below).
What is going on there: I have a custom ObjC class extending NSObject; in the init method I alloc/init an NSMutableArray and then in a loop, populate it with NSMutableArrays. This nested array is declared as a property and released in dealloc(). It lives for the life of the app.
Am I doing this wrong? I don't understand the alert#3: # object not referenced in this execution path and has a retain count of +1.
Since my class allocs the outer array, it owns it and will clean it up. Do the inner arrays need to be released?
Thanks for any tips - still new at this.
EDIT/ADDITION
Trying to stamp out the additional memory warnings I am getting so I thought I would add to the question here in the event someone stumbles upon this w/ the same issue.
I am getting the following alert with the code below (the 2nd line "[keyArray addObject: etc"). What is going on: I have a custom class (Key - based on NSObject) that I instance and store in an array. Based on answers to my previous question, I guess my alloc increases the retain count and then when it is added to the array, the retain count isn't decremented - so the memory warning occurs.
What is the proper way to handle something like this? Use a placeholder like this:
Key * k = [[Key alloc] initKeyWithPath:path isBlackKey:NO]];
[keyArray addObject: k];
[k release];
Is that the proper way to do it? Or is there I way to write the custom class to return an autoreleased obj? (thanks and sorry to be so long winded!).
Potential leak of an object allocated on line 460
Method returns an Objective-C object with a +1 retain count (owning reference)
Object allocated on line 460 is not referenced later in this execution path and has a retain count of +1 (object leaked)
-(void) addOctaveToArraysWithTransform:(CGAffineTransform*)trans andPath: (CGMutablePathRef) path
{
path = [self createCF_keyUsingTransform: trans];
[keyArray addObject:[[Key alloc] initKeyWithPath:path isBlackKey:NO]];
}
Key.h
#import <Foundation/Foundation.h>
#import "Key.h"
#interface Key : NSObject {
#public
CGMutablePathRef keyPath;
BOOL isBlackKey;
NSValue * path;
int keyState;
BOOL needsRedraw;
}
#property (nonatomic, assign) int keyState;
#property (nonatomic, assign) BOOL needsRedraw;
#property (nonatomic) CGMutablePathRef keyPath;
-(id) initKeyWithPath:(CGMutablePathRef) aPath isBlackKey:(BOOL)flag;
-(CGMutablePathRef) getKeyPath;
#end
Key.m
#import "Key.h"
#implementation Key
#synthesize keyState, needsRedraw, keyPath;
-(id) initKeyWithPath:(CGMutablePathRef) aPath isBlackKey:(BOOL)flag
{
if ((self = [super init])){
isBlackKey = flag;
keyState = 0;
needsRedraw = NO;
keyPath = aPath;
CGPathRetain(keyPath);
}
return self;
}
-(CGMutablePathRef) getKeyPath
{
return keyPath;
}
#end
Yes, you have to release the inner arrays to balance the alloc/init. Remember the outer array will retain each inner array, and the outer array will presumably release those later. But here you are still responsible for the alloc/init you just did.
Hope that helps.
You have an allocation of an NSMutableArray on each iteration of the for-loop. Instead use: NSMutableArray array] which is a convenience method that return an autoreleased NSMUtableArray suitable for adding to fieldNotes which will retain the NSMutableArray.

How to access an Objective C variable from different view controllers?

I need to call:
#property (nonatomic, retain) IBOutletCollection(UIButton) NSArray *buttons;
from viewcontroller x but be able to access and set the button colors from view controller y. Basically I'm making a settings page that allows different color schemes. Any ideas? Thanks!
You can use delegation.
Basically, viewcontroller y would be a delegate of viewcontroller x, and every time someone changes the settings page, you viewcontroller x would notify viewcontroller y of that change. X would notify Y like so:
[delegate doSomething withParameter: parameter]
Viewcontroller y would then perform certain methods with that parameter (the variable you're trying to pass).
There are a couple of other things involved, so you should read up on delegation
You need to pass references to your view controller X when instantiating view controller Y:
ViewControllerY *viewController = [[[ViewControllerY alloc] initWithNibName:#"ViewControllerY" bundle:nil] autorelease];
viewController.viewControllerX = myRefToViewControllerX; //declare a property on your ViewControllerY
//show view controller Y

Cocoa Objective-C adding subviews

I have a game application (cocoa, not cocoa touch) where I am trying to add map elements. My app window is named mainWin. I have a subview of mainWin named viewGameMap, which I added in IB. I have a class called room.h/room.m which basically takes dimensions generated in the app for width and height of the room.
I can do this:
room* thisRoom = [[room alloc] initWithFrame: NSMakeRect(441.0-roomWidth,520.0-roomLength, roomWidth * 10, roomLength * 10)];
[[mainWin contentView] addSubview:thisRoom];
But I really want to add this subview to viewGameMap, can I subview a subview? In IB I noticed that a subview doesn't have a contentView so I'm not sure how I would place it there.
In a related question, these room views wouldn't be permanent so how do I destroy them once I am finished with them.
Thanks
First, if you declare viewGameMap in your .h file, like this (using #property directive):
#property (nonatomic, retain) IBOutlet UIView *viewGameMap;
or even just in actual declaration, like this:
IBOutlet UIView *viewGameMap;
then you should be able to bind viewGameMap to appropriate UIView within IB. This will give you direct access to viewGameMap.
Second, since you are using alloc to instantiate your Room object (n.b., class Room should be capitalized per convention), you are responsible for it (you own it). But when you call -addSubview:, then [mainWin contentView] also owns thisRoom. So, you can do this:
room* thisRoom = [[room alloc] initWithFrame: NSMakeRect(441.0-roomWidth,520.0-roomLength, roomWidth * 10, roomLength * 10)];
[viewGameMap addSubview:thisRoom];
[thisRoom release];
Later, when thisRoom is removed from [mainWin contentView], its reference count will (barring some other referencing) drop to zero and it will, ultimately, get deallocated.

Resources