Sharing data between model and custom view?
Hello fellow Cocoa developers!
I'm writing an application that allows the user to fill rectangles in a 8x8 grid, to make fonts. The user will then be able to save the bitmap of this font as a file. The problem comes when I implement the
"-(void)mouseDown:(NSEvent*)theEvent" method in the EditorView.m class. This method is supposed to fill out a rectangle at the correct grid location, and put a 1 in the correct index of the
"int bitmap[64];" array, declared in BitmapModel.h. What is causing me struggle at this point, is that if I create a new BitmapModel instance in each "mouseDown" method call, it'll redeclare the "bitmap" array, and therefore erasing all of the recorded data. I thought that I would be able to solve this by declaring "bitmap" static. But apparently "static" doesn't have the same meaning in Objective-C as in Java. In Java all data declared static is shared by all instances of the object in which the data is declared! So the actual question is: How can I make it possible for EditorView's "mouseDown" method to manipulate "bitmap" without redeclaring it, in each method call?
C++ has static objects (class wide objects). The semantics are slightly different in C++, however they achieve the same end. Obj/C (to my knowledge) doesn't have static objects in class objects.
However, you can use static in C outside a class and this create a singleton - visible everywhere in the whole program. And in your case, this will probably work just about as well. You can do something like this.
// myClass.h
@interface myClass
.....
@end
//
myClass* theOneAndOnlyMyClass ; // this provides the storage for the global pointer
myClass TheOneAndOnlyMyClass ; // this provides the storage for the object
int main(.....)
{
// first statement
theOneAndOnlyMyClass = &TheOneAndOnlyMyClass ; // assign the visible global point to the address of the object in this file
.....
}
in any .m you want to use this:
#import "myClass.h"
[ theOneAndOnlyMyClass doWhatEverYouWant]; // talk to the global instance
Hope that helps.
C++ has static objects (class wide objects). The semantics are slightly different in C++, however they achieve the same end. Obj/C (to my knowledge) doesn't have static objects in class objects.However, you can use static in C outside a class and this create a singleton - visible everywhere in the whole program. And in your case, this will probably work just about as well. You can do something like this.// myClass.h@interface myClass.....@endextern "C" myClass* theOneAndOnlyMyClass ; // this is giving it visible scope//in main.m#include "myClass.h"myClass* theOneAndOnlyMyClass ; // this provides the storage for the global pointermyClass TheOneAndOnlyMyClass ; // this provides the storage for the objectint main(.....){ // first statement theOneAndOnlyMyClass = &TheOneAndOnlyMyClass ; // assign the visible global point to the address of the object in this file .....}in any .m you want to use this:#import "myClass.h" [ theOneAndOnlyMyClass doWhatEverYouWant]; // talk to the global instanceHope that helps.
-clanmills
Thanks a lot for the quick reply, clanmills :).
As usually (you've helped me before, on my other account) seeing your perspective of "problems" have opened the eyes of a relatively new Cocoa programmer, for new techniques in the Objective-C language. My only concern with your suggested code, is this: "extern "C" myClass* theOneAndOnlyMyClass;". No matter where I add it (in whatever file) I get this error message in Xcode: expected identifier or '(' before string constant.
This is the current location of the declaration:
#import <Cocoa/Cocoa.h>
@interface BitmapModel : NSObject{
int bitmap[64];
}
extern "C" BitmapModel *modelInstance;
@end
Hi Ben
Woops, my error. It should be:
#import <Cocoa/Cocoa.h>
@class BitmapModel ;
extern BitmapModel* modelInstance ;
@interface BitmapModel : NSObject {
... whatever ...
}
(extern "C" is legal C++ syntax for a different purpose which we don't want to discuss).
Hi Ben
I've written a little program "TwoDialogs" which is an application with two dialog boxes. It's no thrills of course - you can press the "press me" button in either dialog and the counter will be updated in both boxes. This isn't done using bindings or anything ingenious - it's very simple. They use the @class Dialog1; extern Dialog1 dialog1 ; linking I described above. When you press the button, they simply call [dialog1 increment]; [dialog 2 increment];. So it's two quite separate dialog boxes, linked as described. I hope that helps.
Woops, I didn't enclose the link: http://clanmills.com/articles/cocoatutorials/TwoDialogs.zip
I've very excited, this is post #200 in six months of being on this forum.
Woops, I didn't enclose the link: [url]I've very excited, this is post #200 in six months of being on this forum.
-clanmills
Thanks :).
And congratulations for reaching the 200 posts mark!
Thanks.
I've just noticed that the bulletin board software has promoted me from "regular" to "superstar". Nobody's ever called me that before. I guess in forum land anybody can be a "superstar" - all you need to do is press the reply button 200 times.
I seem to recall I was promoted from "novice" to "regular" at 50 (or maybe it was 100, I've forgotten).
Ta-da! You're automatically famous then. ;)