Re: Correct use of NSViewController

2008-03-21 Thread Cathy Shive
It's so interesting to me to see different people's way of dealing  
with this.  Seems like everyone's design is very similar - they just  
differ in the implementation details.


I hope Apple will fill in the blanks in the framework eventually.  We  
have all come to the same solution in a certain way, but it would be  
easier for us to help each other if we were using the same architecture.


Still, pretty interesting :)

Cathy

On Mar 22, 2008, at 4:31 AM, Steve Weller wrote:



On Mar 21, 2008, at 2:31 PM, Cathy Shive wrote:
1,  window is about to close (wish there was a more reliable place  
to do this, but it has to be before dealloc):


windowController:

- (void)windowWillClose
{
	[mViewController removeObservations]; // this causes the method  
to be called all the way down the view controller tree

}

2.  view controller removes it's observations

viewController:

- (void)removeObservations
{
	[wArrayController removeObserver:self  
forKeyPath:@"selectedObjects"];

[super removeObservations];
}

3.  The document closes and the window controller is released and  
dealloced:


window controller:
- (void)dealloc
{
[mViewController release];
[super dealloc];
}

3.  The first view controller is released and dealloced:

viewController:
- (void)dealloc
{
[mSubcontrollers release];
[super dealloc];
}


I do a very similar thing, but name things differently. Instead of  
telling the lower objects what to do (remove observations) I tell  
them what is happening at the high level so they can do their own  
thing based on that (window is closing.. so I'll remove my  
observers). This lets me keep everything out of dealloc except for  
memory management. In that way if I switch to GC it will still work.



--
Blog:  http://www.bagelturf.com/   Photos: http:// 
bagelturf.smugmug.com/







___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]


Re: Correct use of NSViewController

2008-03-21 Thread Steve Weller


On Mar 21, 2008, at 2:31 PM, Cathy Shive wrote:
1,  window is about to close (wish there was a more reliable place  
to do this, but it has to be before dealloc):


windowController:

- (void)windowWillClose
{
	[mViewController removeObservations]; // this causes the method to  
be called all the way down the view controller tree

}

2.  view controller removes it's observations

viewController:

- (void)removeObservations
{
[wArrayController removeObserver:self forKeyPath:@"selectedObjects"];
[super removeObservations];
}

3.  The document closes and the window controller is released and  
dealloced:


window controller:
- (void)dealloc
{
[mViewController release];
[super dealloc];
}

3.  The first view controller is released and dealloced:

viewController:
- (void)dealloc
{
[mSubcontrollers release];
[super dealloc];
}


I do a very similar thing, but name things differently. Instead of  
telling the lower objects what to do (remove observations) I tell them  
what is happening at the high level so they can do their own thing  
based on that (window is closing.. so I'll remove my observers). This  
lets me keep everything out of dealloc except for memory management.  
In that way if I switch to GC it will still work.



--
Blog:  http://www.bagelturf.com/   Photos: http://bagelturf.smugmug.com/




___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]


Re: Correct use of NSViewController

2008-03-21 Thread Steve Weller


I'm going down this same path I think. I have a split view with a  
browser and a document. The way I solve it is to have the window  
controller have outlets to the scroll views of the two panes of the  
split view. Then in the window controller I do this:


- (void)windowDidLoad {
[super windowDidLoad];

// Create the browser view controller and give it its data source
	browserViewController = [[BTPPBrowserViewController alloc]  
initWithScrollView:browserScroller];

[browserViewController setDataSource:[[self document] imageStorage]];
[browserViewController windowDidLoad];  // Allow controller to set up


I split the initialization into two parts: the initialization of the  
view controller where I provide the superview, and the the  
windowDidLoad method where I let it finish setting up now it has its  
data source (owned by the document). To tear it down I use:


// Window will close
-(void)windowWillClose:(NSNotification *)notification;
{
// Tell all the view controllers that the window will close
[browserViewController windowWillClose];
}

Of course I will add more view controllers as I create them.

My view controllers hide the view implementation from the higher  
levels. My browser is an IKBrowwserView, so I have limited control  
over it.


Of course I am still learning, so all of this may be fatally flawed


On Mar 20, 2008, at 2:53 AM, Cathy Shive wrote:


Jonathan,

I just wanted to say one more thing.  I was re-reading what you had  
written and I see the problem you're having with setting up the  
frame for that first split view.


The problem isn't just the set up of your view controllers and the  
order of creating/adding views, you're also dealing with the issue  
of setting an auto-resizing mask for your view.  Wouldn't it be  
great if your view controller for the split view could just  
configure the view to "fill" it's size to match the size of it's  
superview instead of having to explicitly size and position it when  
it's created?  This is a flaw in this system.  The sub view  
controller has to be able to access the view of its super controller  
so that it can inspect its frame.   With the way autoresizing  
currently works in NSView, you're never going to get around this.


So the part of my system that I haven't described, because I just  
realized that it is important to this issue, is that I have coded my  
own resizing behavior into my NSView subclass to add these kinds of  
features.  I have a "FillWidthAndHeight" option, for instance (I use  
this one most often). This way I don't have to know the super view's  
frame when I add a subview.  At the end of the original window  
controller's init method, I just reset the frame of the window, and  
NSView goes through the view hierarchy and they all size themselves  
correctly within their superviews.  In fact, when I create my views,  
many of them are initialized with an NSZeroRect and the first thing  
my window controller does is set the content view of the window to  
be one of my NSView subclasses.  This topic is much more difficult  
to tackle, but if you want a truly dynamic view system, your view  
code needs to be able to work without any prior knowledge about the  
super view's and sibling view's frames.


IMHO, this is the the Pandora's Box when it comes to working with  
the view hierarchy.  The standard autoresizing mechanism isn't  
really built to handle dynamic layout changes.  You always have to  
know the exact size of your view and its position within its  
superview (and sometimes the size and position of sibling views)  
before you set it.


If you need to program a complex, dynamic view system where sizing  
and positioning managed in the code, first subclass NSView and  
figure out a way to deal with autoresizing.  Maybe this is a bigger  
project than you have time take on right now and maybe its  
unnecessary for the scope of your project, but you're going to bang  
your head against this issue over and over again as you develop more  
dynamic layouts.


It's important to keep in mind the fact that NSView's autoresizing  
and NSWindowController were created to support interfaces that get  
laid out in IB and don't change much after their awake from nib state.


I really hope that I haven't made the issue more complicated for you!

Cathy


On Mar 20, 2008, at 2:19 AM, Jonathan Dann wrote:


Hi Cathy,

Thanks for the comprehensive answer to my question, I wanted to  
make sure that I wasn't committing heresy by going down the 'tree  
of view controllers' road before jumping in and refactoring all my  
code.  I was hoping to set it up so I could forget about most of  
the memory management as I'm replacing views all over the place at  
runtime.


Out of interest, when I add my main split view, I then have to set  
its size to fit my document window's content view.  As this task is  
view-related it seems like it the split view's NSViewController  
sh

Re: Correct use of NSViewController

2008-03-21 Thread Cathy Shive
Yeah, this is something I ran into dealing with the fact that I have  
several key value observations set up.  The way I deal with it is to  
give my view controller's abstract superclass a -(void) 
removeObservations method.  I set it up to work similarly to how you  
use the -(void)dealloc method.  A subclass removes all observations  
that it is registered for and bindings and call's super's  
implementation.  The super call makes sure all the subcontrollers get  
the message as well.


I call this method on the first level controller in from the window  
controller in NSWindow's delegate method, - (void)windowWillClose.   
It's the only place I can think to have this happen at the right  
time.  It has to be before the window controller gets released by the  
document and dealloced.


when the window controller's dealloc is called, it just releases its  
view controller.  the view controller superclass releases its mutable  
array of subcontrollers.


don't retain the window controller in the view controller class.   
This should just be a weak reference.  I think you're doing that right.



so for me:

1,  window is about to close (wish there was a more reliable place to  
do this, but it has to be before dealloc):


windowController:

- (void)windowWillClose
{
	[mViewController removeObservations]; // this causes the method to  
be called all the way down the view controller tree

}

2.  view controller removes it's observations

viewController:

- (void)removeObservations
{
[wArrayController removeObserver:self forKeyPath:@"selectedObjects"];
[super removeObservations];
}

3.  The document closes and the window controller is released and  
dealloced:


window controller:
- (void)dealloc
{
[mViewController release];
[super dealloc];
}

3.  The first view controller is released and dealloced:

viewController:
- (void)dealloc
{
[mSubcontrollers release];
[super dealloc];
}

Everything gets released and dealloced and all observations were  
removed before deallocs were called.


Now, I'm not sure about how to deal with bindings that you set up in  
Interface Builder in terms of controlling *when* the bindings are  
removed and the role of the "representedObject" in all of this.   
Would have to do a little bit of research on that.



On Mar 21, 2008, at 9:49 PM, Jonathan Dann wrote:


Hi Cathy and Paul,

Thanks to you both for your help, I'm really starting to get  
somewhere with this now.


I now have a view controller hierarchy that reflects the views in  
my app.  I've defined my own view controller subclass that I use  
and an abstract superclass for the view controllers I use in the  
app.  To this 'ESViewController' class I've added a, parent ivar, a  
mutable children array and a few indexed accessor methods for that.


To add a new view controller to the hierarchy I use -addChild: 
(ESViewController *)vC which has the side-effect of setting the  
parent and (originally) the window controller of the child.  The  
parent will be the view controller that calls -addChild: and the  
window controller of the 'root' view controller of the tree is set  
when I first make the root view controller.


Cathy, your suggestion of adding the window controller to the views  
and their children so I could get the document seemed to work at  
first, but I kept getting a warning when closing my document.  One  
of my children view controllers had an NSObjectController with the  
content binding set to @"file's owner.windowController.document",  
which worked fine until I tried to close the document.  I was told  
that the window controller was being deallocated while key-value  
observers were still registered with it, which I assume was the  
NSObjectController further down in the view hierarchy.


I think this has something to do with retains, as the window  
controller was not retained by the view controllers, I couldn't get  
my head around who should retain who as my -dealloc methods look  
like this:


// ESViewController (inherits from NSViewController and used as  
abstract superclass for all my view controllers)


- (void)dealloc;
{
parent = nil; // non-retained ivar
self.children = nil;
windowController = nil;
[super dealloc];
}

// ESWindowController  (my window controller for my document)
- (void)dealloc
{
	self.rootViewController = nil; // rootViewController is an  
instance of ESSplitViewController which places a split view in the  
window's content view)

[super dealloc];
}

My windowController's -awakeFromNib method set the root view  
controller, which when instantiated created its children, setting  
their window controllers and parents as such


// ESWindowController
- (void)awakeFromNib;
{
	ESSplitViewController *root = [[ESSplitViewController alloc]  
initWithNibName:@"SplitView" bundle:nil];

[root setWindowController:self];
[self setRootViewController:root];
[root release];
  

Re: Correct use of NSViewController

2008-03-21 Thread Jonathan Dann

Hi Cathy and Paul,

Thanks to you both for your help, I'm really starting to get somewhere  
with this now.


I now have a view controller hierarchy that reflects the views in my  
app.  I've defined my own view controller subclass that I use and an  
abstract superclass for the view controllers I use in the app.  To  
this 'ESViewController' class I've added a, parent ivar, a mutable  
children array and a few indexed accessor methods for that.


To add a new view controller to the hierarchy I use -addChild: 
(ESViewController *)vC which has the side-effect of setting the parent  
and (originally) the window controller of the child.  The parent will  
be the view controller that calls -addChild: and the window controller  
of the 'root' view controller of the tree is set when I first make the  
root view controller.


Cathy, your suggestion of adding the window controller to the views  
and their children so I could get the document seemed to work at  
first, but I kept getting a warning when closing my document.  One of  
my children view controllers had an NSObjectController with the  
content binding set to @"file's owner.windowController.document",  
which worked fine until I tried to close the document.  I was told  
that the window controller was being deallocated while key-value  
observers were still registered with it, which I assume was the  
NSObjectController further down in the view hierarchy.


I think this has something to do with retains, as the window  
controller was not retained by the view controllers, I couldn't get my  
head around who should retain who as my -dealloc methods look like this:


// ESViewController (inherits from NSViewController and used as  
abstract superclass for all my view controllers)


- (void)dealloc;
{
parent = nil; // non-retained ivar
self.children = nil;
windowController = nil;
[super dealloc];
}

// ESWindowController  (my window controller for my document)
- (void)dealloc
{
	self.rootViewController = nil; // rootViewController is an instance  
of ESSplitViewController which places a split view in the window's  
content view)

[super dealloc];
}

My windowController's -awakeFromNib method set the root view  
controller, which when instantiated created its children, setting  
their window controllers and parents as such


// ESWindowController
- (void)awakeFromNib;
{
	ESSplitViewController *root = [[ESSplitViewController alloc]  
initWithNibName:@"SplitView" bundle:nil];

[root setWindowController:self];
[self setRootViewController:root];
[root release];
root =  nil;
}

// ESSplitViewController
- (id)initWith..
{
if (![super init])
return nil;
	ESOutlineViewController *oVC = [[ESOutlineViewController alloc]  
initWithNibName:@"OutlineView" bundle:nil]; // the OutlineView nib has  
the NSObjectController that causes the deallocation grief
	ESTextViewController *tVC = [[ESTextViewController alloc]  
initWithNibName:@"TextView" bundle:nil];

[self addChild:oVC];
[self addChild:tVC];
[oVC release];
[tVC release];
return self;
}

- (void)addChild:(ESViewController *)child;
{
[child addObject:child];
[child setWindowController:self.windowController];
[child setParent:self];
}

So the way I expected it to work, when deallocating was as follows

windowController gets a -dealloc call
rootViewController gets released and -dealloc'd
childrenViewControllers get released and -dealloc'd
at the end of all this the control returns to the windowController's - 
dealloc method which proceeds to call [super dealloc];


Some amount of logging later showed me that my windowController was  
calling super before the children began their dealloc methods, which  
leads me to assume that maybe the unbinding of the NSObjectController  
couldn't happen as the windowController to which it was bound was  
already gone.


So this boils down to a couple of ideas

Why could the window controller complete it's deallocation before the  
children view controllers have, when they are definitely not retained  
elsewhere?
Should the view controllers have retained the window controller and/or  
their parent (instinct leads me to think this would cause retain  
cycles as the window controller will not call -dealloc as it is  
retained by view controllers which it needs to release first).


I later changed this code with Paul's suggestion of using the  
represented object as a pointer to my document subclass and all this  
went away.  The -addChild method now sets the represented object of  
the child to that of its parent instead of the window controller.  Am  
I right in thinking that because of the document architecture the  
document cannot be deallocated until the window controller is, so  
deallocating the window controller removes the binding before the  
document receives -dealloc.  In that case, if I did wish to bind  
some

Re: Correct use of NSViewController

2008-03-20 Thread Paul Szego


On 21/03/2008, at 12:35 AM, Jonathan Dann wrote:




Hi Cathy,

Thanks again for your advice. I've got it working now and I'm almost  
back I where I was before refactoring, I'm now running into a  
bindings problem.


Before using the view controllers I had put 2 tree controllers in my  
window controller's nib, 2 outline views were then bound to these  
and the tree controllers themselves got their content from an object  
controller that was bound to the the keypath [(Window  
Controller)File's Owner].document. So the object controller was a  
proxy for my document and the tree controllers had shorter keypath  
to traverse to get to the array they needed in my document subclass.


Now when I do this I have the tree controllers and the document  
proxy object controller in my view controller's nib. The only way I  
can see to getting to the document is using the keypath



Have you considered using the representedObject property of the  
NSViewController?


To quote the API docs for NSViewController:

"...a generic representedObject property, to make it easy to establish  
bindings in the nib to an object that isn't yet known at nib-loading  
time or readily available to the code that's doing the nib loading."


In my code I create the view controller from the window controller,  
then set the representedObject. In my case it's usually the document,  
since I have the necessary controller objects in the document so that  
I can share selection status across various windows and views from  
different NIB's easily (remember that NSDocument is part of the  
*controller* layer in MVC, not the model).


HTH, Paul.

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]


Re: Correct use of NSViewController

2008-03-20 Thread Cathy Shive
Yeah, the document.   The window controller and document have a  
relationship, but this isn't true for the view controllers and the  
document.  Again, this is part of NSViewController's ambiguous role  
in this whole architecture.  I don't really know how this *should* be  
dealt with.


It seems like those two key paths would lead to the same thing, but  
obviously some connection isn't being made the way you are  
expecting.  I suspect it has something to do with the fact that the  
binding is being set before the view controller's view is actually  
added to the view hierarchy, so that view's window isn't the window  
controller's window yet which means you have no direct path to the  
window controller's document at that moment.


What if you give your view controllers a reference to the window's  
window controller when you create them?


Your window controller is obviously the first thing to exist.  It  
allocates and initializes the first view controller.  If you  
initialize it with a method like:


- (id)initWithWindowController:(NSWindowController*)theWindowController;

Then they could set their window controller right before they load  
their nibs.


The nibs could use this keypath instead:

@"filesowner.windowController.document"

That should hook up correctly if you have a windowController ivar in  
your NSViewController subclass.



On Mar 20, 2008, at 12:35 PM, Jonathan Dann wrote:




Hi Cathy,

Thanks again for your advice. I've got it working now and I'm  
almost back I where I was before refactoring, I'm now running into  
a bindings problem.


Before using the view controllers I had put 2 tree controllers in  
my window controller's nib, 2 outline views were then bound to  
these and the tree controllers themselves got their content from an  
object controller that was bound to the the keypath [(Window  
Controller)File's Owner].document. So the object controller was a  
proxy for my document and the tree controllers had shorter keypath  
to traverse to get to the array they needed in my document subclass.


Now when I do this I have the tree controllers and the document  
proxy object controller in my view controller's nib. The only way I  
can see to getting to the document is using the keypath


[File's Owner].view.window.windowController.document

However this does not work, seems convoluted, and I get the following:

KVO autonotifying only supports -set: methods that return  
void. Autonotifying will not be done for invocations of - 
[NSSplitView _setWindow:]


So my view controller needs to know about its 'owning' document  
somehow and I can't see how to get it.


Have you run into this. I'm not sure getting the current document  
from the document controller will work as that will change ad the  
user opens more documents.


Thanks again,

Jon

P.S. Out of interest, what do you develop?


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]


Re: Correct use of NSViewController

2008-03-20 Thread Jonathan Dann



Hi Cathy,

Thanks again for your advice. I've got it working now and I'm almost  
back I where I was before refactoring, I'm now running into a bindings  
problem.


Before using the view controllers I had put 2 tree controllers in my  
window controller's nib, 2 outline views were then bound to these and  
the tree controllers themselves got their content from an object  
controller that was bound to the the keypath [(Window Controller) 
File's Owner].document. So the object controller was a proxy for my  
document and the tree controllers had shorter keypath to traverse to  
get to the array they needed in my document subclass.


Now when I do this I have the tree controllers and the document proxy  
object controller in my view controller's nib. The only way I can see  
to getting to the document is using the keypath


[File's Owner].view.window.windowController.document

However this does not work, seems convoluted, and I get the following:

KVO autonotifying only supports -set: methods that return void.  
Autonotifying will not be done for invocations of -[NSSplitView  
_setWindow:]


So my view controller needs to know about its 'owning' document  
somehow and I can't see how to get it.


Have you run into this. I'm not sure getting the current document from  
the document controller will work as that will change ad the user  
opens more documents.


Thanks again,

Jon

P.S. Out of interest, what do you develop?
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]


Re: Correct use of NSViewController

2008-03-20 Thread Cathy Shive

Jonathan,

I just wanted to say one more thing.  I was re-reading what you had  
written and I see the problem you're having with setting up the frame  
for that first split view.


The problem isn't just the set up of your view controllers and the  
order of creating/adding views, you're also dealing with the issue of  
setting an auto-resizing mask for your view.  Wouldn't it be great if  
your view controller for the split view could just configure the view  
to "fill" it's size to match the size of it's superview instead of  
having to explicitly size and position it when it's created?  This is  
a flaw in this system.  The sub view controller has to be able to  
access the view of its super controller so that it can inspect its  
frame.   With the way autoresizing currently works in NSView, you're  
never going to get around this.


So the part of my system that I haven't described, because I just  
realized that it is important to this issue, is that I have coded my  
own resizing behavior into my NSView subclass to add these kinds of  
features.  I have a "FillWidthAndHeight" option, for instance (I use  
this one most often). This way I don't have to know the super view's  
frame when I add a subview.  At the end of the original window  
controller's init method, I just reset the frame of the window, and  
NSView goes through the view hierarchy and they all size themselves  
correctly within their superviews.  In fact, when I create my views,  
many of them are initialized with an NSZeroRect and the first thing  
my window controller does is set the content view of the window to be  
one of my NSView subclasses.  This topic is much more difficult to  
tackle, but if you want a truly dynamic view system, your view code  
needs to be able to work without any prior knowledge about the super  
view's and sibling view's frames.


IMHO, this is the the Pandora's Box when it comes to working with the  
view hierarchy.  The standard autoresizing mechanism isn't really  
built to handle dynamic layout changes.  You always have to know the  
exact size of your view and its position within its superview (and  
sometimes the size and position of sibling views) before you set it.


If you need to program a complex, dynamic view system where sizing  
and positioning managed in the code, first subclass NSView and figure  
out a way to deal with autoresizing.  Maybe this is a bigger project  
than you have time take on right now and maybe its unnecessary for  
the scope of your project, but you're going to bang your head against  
this issue over and over again as you develop more dynamic layouts.


It's important to keep in mind the fact that NSView's autoresizing  
and NSWindowController were created to support interfaces that get  
laid out in IB and don't change much after their awake from nib state.


I really hope that I haven't made the issue more complicated for you!

Cathy


On Mar 20, 2008, at 2:19 AM, Jonathan Dann wrote:


Hi Cathy,

Thanks for the comprehensive answer to my question, I wanted to  
make sure that I wasn't committing heresy by going down the 'tree  
of view controllers' road before jumping in and refactoring all my  
code.  I was hoping to set it up so I could forget about most of  
the memory management as I'm replacing views all over the place at  
runtime.


Out of interest, when I add my main split view, I then have to set  
its size to fit my document window's content view.  As this task is  
view-related it seems like it the split view's NSViewController  
should handle the size calculation and placing of the view in the  
correct place in the window.  I allocate and instantiate my view  
controller in my NSWindowController subclass, then set the split  
view as a subview of the content view and then  in the - 
awakeFromNib of the view controller I get the split view's  
superview's (the content view's) frame, doing my resiing from there.


Would you do the same, as this seems to encapsulate the logic  
properly, or would you just set it all in the window controller?


Thanks again, you've been really helpful.

Jonathan


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]


Re: Correct use of NSViewController

2008-03-20 Thread Cathy Shive
I would do it exactly like you described.   Seems to me that your  
instincts are pretty much on the mark.  In your case, the window  
controller could take care of creating that first main split view,  
but I would do it in the first level of the view controller  
controller tree for logical consistency.  So in a set up like mine  
and maybe yours, the window controller is only responsible for the  
window's content view.  It creates the first view controller, asks it  
for its view (the split view) and adds it as a subview to its own  
view (the window's content view).  And actually, when the window  
controller asks that first view controller for its view, if things  
are set up right in the controller tree, that view should contain the  
entire view hierarchy, which was built in nice little steps by each  
sub-controller in the tree.


I recently had to refactor my view controller set up because I  
started to notice similar bloat and spaghetti code creeping into the  
app.  I had all of the same questions you do about where things  
should happen.  :)   It was a bit tricky at first, but things fell  
into place and it feels very solid and clean to me now.  I also deal  
with a lot of dynamic adding/removing views.


Actually, I sent a bug report (Bug ID# 5794739)  to Apple last week  
because the documentation on "Document-Based Application Architecture"


http://developer.apple.com/documentation/Cocoa/Conceptual/Documents/ 
Concepts/OverviewDocArchitecture.html#//apple_ref/doc/uid/2023- 
BAJBBBAH


hasn't been updated to explain the role of the new NSViewController  
class in this design.  Also, the issue you are dealing with now and  
that I dealt with a couple of weeks ago seems like it should already  
be dealt with in the design NSViewController.  As it is, it's very  
unclear what you're supposed to do with this class.


Anyway, best of luck, you seem to already know what you have to do :)

Cathy


On Mar 20, 2008, at 2:19 AM, Jonathan Dann wrote:


Hi Cathy,

Thanks for the comprehensive answer to my question, I wanted to  
make sure that I wasn't committing heresy by going down the 'tree  
of view controllers' road before jumping in and refactoring all my  
code.  I was hoping to set it up so I could forget about most of  
the memory management as I'm replacing views all over the place at  
runtime.


Out of interest, when I add my main split view, I then have to set  
its size to fit my document window's content view.  As this task is  
view-related it seems like it the split view's NSViewController  
should handle the size calculation and placing of the view in the  
correct place in the window.  I allocate and instantiate my view  
controller in my NSWindowController subclass, then set the split  
view as a subview of the content view and then  in the - 
awakeFromNib of the view controller I get the split view's  
superview's (the content view's) frame, doing my resiing from there.


Would you do the same, as this seems to encapsulate the logic  
properly, or would you just set it all in the window controller?


Thanks again, you've been really helpful.

Jonathan


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]


Re: Correct use of NSViewController

2008-03-19 Thread Jonathan Dann

Hi Cathy,

Thanks for the comprehensive answer to my question, I wanted to make  
sure that I wasn't committing heresy by going down the 'tree of view  
controllers' road before jumping in and refactoring all my code.  I  
was hoping to set it up so I could forget about most of the memory  
management as I'm replacing views all over the place at runtime.


Out of interest, when I add my main split view, I then have to set its  
size to fit my document window's content view.  As this task is view- 
related it seems like it the split view's NSViewController should  
handle the size calculation and placing of the view in the correct  
place in the window.  I allocate and instantiate my view controller in  
my NSWindowController subclass, then set the split view as a subview  
of the content view and then  in the -awakeFromNib of the view  
controller I get the split view's superview's (the content view's)  
frame, doing my resiing from there.


Would you do the same, as this seems to encapsulate the logic  
properly, or would you just set it all in the window controller?


Thanks again, you've been really helpful.

Jonathan

smime.p7s
Description: S/MIME cryptographic signature
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]

Re: Correct use of NSViewController

2008-03-19 Thread Cathy Shive

Hi,

My strategy is similar to yours, but it doesn't have to result in  
spaghetti code.  I have a view controller class that contains a list  
of sub-viewcontrollers.  What I end up with is a structure that does  
in fact resemble the actual view hierarchy.


The tricky part is breaking down your window controller into logical  
units that are as self-contained as possible.  In your design, you  
don't want the subcontrollers to have dependencies on each other, or  
you will end up with spaghetti code.  This is where bindings, KVO and  
sometimes notifications come in real handy.


So in the case of Mail.app, I could see a window controller with a  
singe view controller that returns the main split view as its view.   
That controller creates two sub-controllers, the right side and left  
side of the main split view. The left side view controller returns  
the source list as its view and the right side controller returns the  
other split view as its view.


As far as data is concerned, the left side controller's source list  
is displaying a list of mail boxes that may be stored in an array  
controller somewhere else.  Users select a mail box by clicking on  
the source list.  The right side controller (with the detail/compare  
split view) is bound to the "selectedObjects" of that array  
controller.  When users change the selected objects, the right side  
controller is alerted to the change through bindings.  It then gets  
the selected Mail box and displays what it needs to display.  There's  
no reason for the right side and left side controllers to communicate  
with each other, the bindings mechanism takes care of all of that.


Of course, your controllers don't necessarily need to have the  
hierarchical structure of controllers built in to the class.  One  
advantage of having that relationship in place is that when dealloc  
is called on a view controller, it will automatically release all of  
the subcontrollers in its list so that you don't have to worry about  
memory management for these objects.


I know people that keep dictionaries with the view controllers and  
their associated nibs instead of storing them as a tree structure  
like I do.  I don't know which is the best, but I think that your  
instinct that some structure should be there is right.



Hope that helps,
Cathy




On Mar 19, 2008, at 12:37 PM, Jonathan Dann wrote:


Hi guys,

I've ended up with a bloated window controller in my document based  
app and want to refactor my code using done view controllers.  My  
question is really about design.


If I have a split view with which contains a split view (like mail)  
then should I have a controller for the large split view which will  
then contain an ivar that points to a controller for the smaller  
split view?  As a subview of one of the split views I would then  
have a text view that itself needs a view controller, so it seems  
like I'll he ending up with a heirarchy of view controllers that  
reflects the view heirarchy itself. This seems like I'm gong about  
this the wrong way ad would end up with a spaghetti code.


Can anyone give mr a few hints as to how this should he fine properly?

Thanks,

Jon
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/catshive%40gmail.com

This email sent to [EMAIL PROTECTED]


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]


Correct use of NSViewController

2008-03-19 Thread Jonathan Dann

Hi guys,

I've ended up with a bloated window controller in my document based  
app and want to refactor my code using done view controllers.  My  
question is really about design.


If I have a split view with which contains a split view (like mail)  
then should I have a controller for the large split view which will  
then contain an ivar that points to a controller for the smaller split  
view?  As a subview of one of the split views I would then have a text  
view that itself needs a view controller, so it seems like I'll he  
ending up with a heirarchy of view controllers that reflects the view  
heirarchy itself. This seems like I'm gong about this the wrong way ad  
would end up with a spaghetti code.


Can anyone give mr a few hints as to how this should he fine properly?

Thanks,

Jon
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]