objective c - Class Cluster as a Singleton? -
sorry length of post; meant document journey problem.
i have question shared object in cocoa app needs change time time , how best store it's accessible few different places. bear me.
class implementation
the shared object implemented class cluster (i.e., https://stackoverflow.com/a/2459385/327179) looks following (note document
merely class name; not indicative of actual class does):
in document.h
:
typedef enum { documenttypea, documenttypeb } documenttype; @interface document : nsobject {} - (document *) initwithdocumenttype:(nsuinteger)documenttype; - (void) methoda; - (void) methodb; @end
in document.m
:
@interface documenta : document - (void) methoda; - (void) methodb; @end @interface documentb : document - (void) methoda; - (void) methodb; @end @implementation document - (document *)initwithdocumenttype:(nsuinteger)documenttype; { id instance = nil; switch (documenttype) { case documenttypea: instance = [[documenta alloc] init]; break; case documenttypeb: instance = [[documentb alloc] init]; break; default: break; } return instance; } - (void) methoda { return nil; } - (void) methodb { return nil; } @end @implementation documenta - (void) methoda { // ... } - (void) methodb { // ... } @end @implementation documentb - (void) methoda { // ... } - (void) methodb { // ... } @end
how user interacts document
via menu item, user can switch between documenta , documentb @ will.
what happens when "switch" occurs
when user switches from, say, documenta
documentb
, need 2 things happen:
- my primary
nsviewcontroller
(mainviewcontroller
) needs able use new object. - my
appdelegate
needs updatenstextfield
happens located in content border of main window. (fwiw, can seem assign outletnstextfield
inappdelegate
)
the question(s)
i've seen singletons mentioned quite bit way have global reference without cluttering one's appdelegate
(primarily here , here). said, i've not seen info on overwriting such singleton (in our case, when user switches documenta
documentb
[or vice versa], global reference need hold new object). i'm not expert on design patterns, remember hearing singletons not meant destroyed , recreated...
so, given this, here questions:
- how store class cluster (such
mainviewcontroller
,appdelegate
can access appropriately)? - am mixing concerns having both
mainviewcontroller
(who usesdocument
heavily) ,appdelegate
(who manages primary window [and thus,nstextfield
]) have knowledge ofdocument
?
feel free let me know if i'm thinking problem incorrectly; want implementation orthogonal , correct possible.
thanks!
status update #1
thanks advice @jackyboy, here's route i've taken:
document
1 that, upon "switching", "notifies"appdelegate
,mainviewcontroller
passing them newly created instance.- both
appdelegate
,mainviewcontroller
can updatedocument
object via singleton instance necessary.
here new files (dumbed down y'all can see crux of matter):
in document.h
:
#import <foundation/foundation.h> @class appdelegate; @class mainviewcontroller; typedef enum { documenttypea, documenttypeb } documenttype; @interface document : nsobject @property (weak, nonatomic) mainviewcontroller *mainviewcontrollerref; @property (weak, nonatomic) appdelegate *appdelegateref; + (document *)sharedinstance; - (id)initwithparser:(nsuinteger)parsertype; @end
in document.m
:
#import "appdelegate.h" #import "document.h" #import "mainviewcontroller.h" @interface documenta : document // ... @end @interface documentb : document // ... @end @implementation document @synthesize appdelegateref; @synthesize mainviewcontrollerref; + (document *)sharedinstance { static xparser *globalinstance; static dispatch_once_t predicate; dispatch_once(&predicate, ^{ // default, return documenta object (for no particular reason). globalinstance = [[self alloc] initwithdocumenttype:documenta]; }); return globalinstance; } - (id)initwithdocumenttype:(nsuinteger)documenttype { document *instance = nil; switch (parsertype) { case documenttypea: instance = [[documenta alloc] init]; break; case documenttypeb: instance = [[documentb alloc] init]; break; default: break; } // question: right? have store these references // every time new document type initialized? self.appdelegateref = (appdelegate *)[nsapp delegate]; self.mainviewcontrollerref = self.appdelegateref.mainviewcontroller; [self.appdelegateref parserswitchedwithparser:instance]; [self.mainviewcontrollerref parserswitchedwithparser:instance]; return instance; } @end @implementation xparser_nsxml // ... @end @implementation documenta // ... @end
should bothered fact document
has knowledge of existence of appdelegate
, mainviewcontroller
? additionally, should bothered fact when document
object updates, re-notifies both appdelegate
, mainviewcontroller
(even though 1 of initiated update)?
as always, appreciate everyone's eyeballs on quest ideal implementation continues. :)
status update #2
a comment @caleb helped me understand nsnotification
-based setup lot less unwieldy particular problem.
thanks, all!
i don't see need shared object here, less singleton. need find current document @ arbitrary times many different objects? seems more have 2 objects (app delegate , view controller) both need know current document. notifications provide easy way manage that: whenever switch happens, can post nsnotification includes new document. objects need know current document have registered "document switch" notification, , when notification arrives can stash pointer document in instance variable or property.
Comments
Post a Comment