Re: Large over 100K pixel high ruler scroll view
Re: Large over 100K pixel high ruler scroll view
- Subject: Re: Large over 100K pixel high ruler scroll view
- From: Graham Cox <email@hidden>
- Date: Fri, 02 Sep 2011 13:48:51 +1000
On 31/08/2011, at 2:49 PM, Julie Porter wrote:
> I have the idea that a class, MyDocument is instantiated with an array myEvents, each time a file is opened.
No, an OBJECT INSTANCE whose class is MyDocument is created when you open a file. This document object HAS an array, myEvents. This is another object. 'myEvents' is a variable, in this case an instance variable, because there is a separate copy of that variable for each instance of MyDocument. You refer to the NSArray instance through this variable, myEvents, which is simply a pointer to the array object.
You must understand the difference between a class and an instance. The class is just the object's type, the instance is the actual thing in memory that has that type. It's exactly the same as say, an int and a variable whose type is int.
int; // a type
int myInt = 3t; // an actual example of an int, called 'myInt', whose value is 3
Just as a 'naked' int can't exist, you have to have a variable whose type is int, a naked 'MyDocument' can't exist - you have to have a variable whose type is 'MyDocument' (or, in Objective-C, the type must be a pointer, hence the *, but that's just a quirk of Obj-C, and not a key conceptual point).
MyDocument; // a type
MyDocument* anActualDocument = [[MyDocument alloc] init]; // an actual instance of 'MyDocument*', called 'anActualDocument' whose 'value' is whatever the document consists of.
> A separate class MyView is opened by MyDocument by some sort of magic in the controller glue.
No. An OBJECT INSTANCE whose class is MyView is created when the document loads the nib file that contains it. It's not magic, and the term 'open' has no meaning here.
> I can see how the MyView class has no understanding of the myEvents object as there is no clear connection to the MyDocument class other than the controller magic.
Correct (apart from the magic bit). The view has no knowledge of the document object. You need to set up that knowledge in the form of a connection (it's nothing more than a common-or-garden pointer) to the document.
> What I do not get, is why an accessor such as an abstract getObject can not get the Object from the open and instantiated MyDocument class. I guess it need to have a link or line to the object in the MyDocument class, since there is an instance of MyView spawned by the MyDocument, it would seem that there should be a link between the two, but where is this link hidden? Or do I need to make it programmatically?
Your view could have an outlet to the document:
@interface MyView : NSView
{
IBOutlet MyDocument* myActualDocumentInstance;
}
@end
In IB, you can connect this outlet to the document (File's Owner).
In your code, you can access the document from your view:
data = [myActualDocumentInstance graphicsData];
This assumes the document has a method called -graphicsData, which you'd declare:
@interface MyDocument : NSDocument
{
}
- (id) graphicsData
@end
You are asking the instance (not the class) for some data, so you use the name of the variable that points to the instance, and not the name of the document's class, which is just its type. While you can send messages to a class, pretend for the moment that you can't and that [MyDocument graphicsData] is analogous to int->3 or something - sending a message to an int is nonsensical, you need a variable of TYPE int.
(Another aside - do not create a method called getObject as a 'getter' - there are proper naming conventions for property accessors, whether you write them by hand or otherwise. A getter never includes the word 'get'. If your data property is called e.g. graphicsData, then the proper accessors would be named -graphicsData (getter) and -setGraphicsData: (setter))
> This is even more confusing, What does IB have to do with my database and communication between functions? I thought this was for things like buttons and cells so that when one presses a button the value in a cell is passed to the function.
It is, but it also is a convenient place to set up simple pointer connections between objects it knows about. In this case, it 'knows about' both your view and your document instances, so it's a perfectly good place to forge a simple connection between the two, by using outlets (the term 'IBOutlet' is a hint that the variable in question is visible to IB). It makes possible interesting relationships between objects that might be difficult or even impossible to establish in code. For example, your view needs to 'know about' your document. Without a pointer to that document instance, where could it get one? It really can't in a totally reliable way on its own, so simply making that connection in IB cuts through an awful lot of difficulty. It could be argued that this is not strictly to do with 'building an interface' (except in a more abstract sense of building a programmatic interface between different objects), but it's incredibly useful anyway, so who cares whether IB should be doing that or not?
> I think I need to look up the definition of property. That may be what I am not understanding. That I abstract property and key as the same thing.
That seems to me a red herring here. As is using scripts to 'write accessors for you'. Just write them by hand at first. It's a little tedious, but it will confer understanding of what you're actually doing. Later you can use properties to save a bit of time writing the accessors by hand. There is a technology called 'KVC' that lets you treat properties in a more abstract and generic way, but you DO NOT NEED TO USE IT TO SOLVE THIS PROBLEM. In addition, you don't need to use properties to use KVC - hand-written accessors work just fine, as long as you use the correct naming conventions.
> Will attempt to read more on IB Outlet abstractions, but am not sure what an IBOutlet is in relation to my array of events. Which I am pretty sure is the Data Model. (apart from the arrays of dicts I could draw the keys and values using the list view CoreData tools.)
An outlet is just a way to tag a pointer (as an instance variable) so that it's visible to IB. It's the fact that it's a pointer that's important - it allows you to get access to another object.
I assume you understand what a pointer is. If not, you have got no chance of making any headway until you do. Pointers are essential to Objective-C, as they are the sole means by which you refer to an object instance.
> In postscript I have a dictionary open on the stack that contains my array of dictionaries. If I open another dictionary on the stack I can read in my array, but any new define instances are declared in local to the new dictionary. When I close that top level dictionary I can no longer access any local changes.
>
> I think cocoa is the other way around, Where the document which has the array of dictionaries I want is not visible to the View because the view is not open to the document.
I have no idea what this means. I think trying to fit the way Cocoa works into a postscript-type programming model is going to fail miserably. There is no similarity whatsoever. Cocoa and Objective-C first easily into a fairly standard OOP programming model, so going back and learning that approach is likely to bear fruit. Postscript should be left aside, it's not relevant to any of this.
> I also keep seeing stuff relating to KVO. This relates to the really nifty Departments and employees type list, that sort of seem to happen with bindings. But that system will not let me have arrays of dicts inside arrays of dicts unless I can program them through classes or what ever abstraction I am failing to understand. Problem is I am not writing mail or iTunes, that has already been done.
>
> I think KVO is what, in the long term, I want. Connecting things in IB seems even more like going down the wrong path. Again in postscript I have keys and values. This is what is in my dictionary. One key might be @"StartLine" another key abstracts as @"EndLine"
Forget KVO for now as well. It's a neat technology that simplifies certain things, but it can only be cracked once you understand the basics of Cocoa and OOP in general. You do not need KVO to solve your problem, which, despite all that it appears, is incredibly simple. All you need is a simple pointer so that your view can access your document and another one so that your document can access your view. You can create these pointers as outlets and connect them in IB. Job done. Assuming that you need to learn a whole extra layer of complex technology to solve it is confusing you and making the problem seem much more complicated than it is.
> I have keys and values. I want to observe them between classes. Nothing more, nothing less.
No, even simpler. You need to let one object talk to another. You do this using pointers. Nothing more, nothing less.
> Saw the second part relating to OoP as they used to call it. I remember liking smalltalk and Logo, but I was in high school at the time 35 years ago. the world went to procedural programming. A lot of this really feels like a waste of time. Makework for programmers. I thought the point of such was to abstract things so that one can concentrate on the not so common code.
Well, a whole generation of programmers will disagree with you. OOP is much more productive and scalable than procedural ever was. But this is a digression, and not relevant at this point. If you want to write a Cocoa program, you have to learn OOP. You can't avoid it, so complaining that it's not what you know or knew is irrelevant. The point of it is indeed to free you work on your unique code, and it delivers on that - that is exactly what you're doing here. The view will display your graphics without you having to need to know how graphics works, and your document will load your data without you having to need to know how files works. The only bit you need to supply is the connection between one and the other, which is unique to your problem.
> There really should be a framework tutorial out there that works for scrolling graphics the same way one can scroll text. A black box where one only has to deal with the drawRect procedure that is file based.
I'm sure I've seen several.
But break the problem down. You have two issues here. First, you need to be able to get a scrolling view to work. That's pretty easy, and can be done without any reference to any other objects - you can simply add some drawing code in your view that draws things like boxes or lines that require no external definition. All you need is to set the view's frame to something largish in its -initWithFrame: method, and draw some fixed graphics in the -drawRect: method. You will find that this view will scroll correctly when placed in a NScrollView container. That will be a good starting point since it can be written in a few minutes and will give you confidence in views.
The second part is to load data in your document. Maybe you have that working already.
The final part is to tie them together, so that the view doesn't draw fixed graphics but is able to obtain these from the document. In order to do this, the view needs to be able to refer to the document. It can do this via an outlet. Similarly, the document will probably need to set the frame of the view based on the dimensions of the graphic data it loaded. In order to do this, the document needs to be able to refer to the view. It can do this via an outlet.
I seem to have told you how to do this about twenty times now. Honestly, it's really simple. Stop looking at the trees and see the forest!
--Graham
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden