model view controller - Need some tips regarding the Cocoa MVC/KVO patterns -
this wide-ranging/vague question, here goes. apologies in advance.
the app (desktop app) i'm building takes different kinds of input generate qr code (i'm building learn obj-c/cocoa). user can switch between different views allow input of plain text (single text field), vcard/mecard data (multiple text fields), , other stuff. no matter input, result qr code.
to keep things contained, i'd use views view-controllers, handle they're own inputs, , can "send" generic "data encode" object containing data central encoder. i.e. plain text view make data object textfield's text, while vcard/mecard view use of fields make structured vcard/mecard data.
i can bind of stuff manually in code, i'd learn how bindings/kvo me out. alas, after reading apple's developer docs, , simpler tutorials/examples find, i'm still not sure how apply app.
for instance: user edits textfields in vcard-view. vcard view-controller notified of each update , "recalculates" data object. central encoder controller notified of updated data object, , encodes data.
the point of this, input views can created independently, , can contain kinds of input fields. handle own inputs, , "return" generic data object, encoder can use. internally, views observe inputs update data object, , externally encoder needs observe data object.
trouble have no idea how make happen , keep decoupled. should there object controller between input-view , fields? should there 1 between view , encoder? need where? if has link tutorial, please share.
again, can roll own system of notifications , glue code, think point avoid that.
definitely vague question, 1 beginner another, feel pain :)
i downloaded , unpacked every single example , grep through them frequently. i've found valuable thing me on hump. recommend not giving on examples. hacked this script download , unpack them all.
in terms of kvo patterns, found technique described here useful. doesn't work as-is in objective-c 2.0 however. doesn't give detail on how it's used. here's i've got working:
the kvodispatcher.h
this:
#import <foundation/foundation.h> @interface kvodispatcher : nsobject { id owner; } @property (nonatomic, retain) id owner; - (id) initwithowner:(id)owner; - (void)startobserving:(id)object keypath:(nsstring*)keypath options:(nskeyvalueobservingoptions)options selector:(sel)sel; - (void)observevalueforkeypath:(nsstring *)keypath ofobject:(id)object change:(nsdictionary *)change context:(void *)context; @end
and kvodispatcher.m
so:
#import "kvodispatcher.h" #import <objc/runtime.h> @implementation kvodispatcher @synthesize owner; - (id)initwithowner:(id)theowner { self = [super init]; if (self != nil) { self.owner = theowner; } return self; } - (void)startobserving:(id)object keypath:(nsstring*)keypath options:(nskeyvalueobservingoptions)options selector:(sel)sel { // here actual kvo registration [object addobserver:self forkeypath:keypath options:options context:sel]; } - (void)observevalueforkeypath:(nsstring *)keypath ofobject:(id)object change:(nsdictionary *)change context:(void *)context { // event delegated owner // assumed method identified selector takes // 3 parameters 'keypath:object:change:' objc_msgsend(owner, (sel)context, keypath, object, change); // noted, variation of technique // expand data passed in 'initwithowner' , // have data passed selected method here. } @end
then can register observe events so:
kvodispatcher* dispatcher = [[kvodispatcher alloc] initwithowner:self]; [dispatcher startobserving:theobject keypath:@"thepath" options:nskeyvaluechangenewkey selector:@selector(dosomething:object:change:)];
and in same object executed above, can have method so:
- (void) dosomething:(nsstring *)keypath object:(id)object change:(nsdictionary *)change { // thing }
you can have many of these "dosomething" type methods like. long use same parameters (keypath:object:change:) work out. 1 dispatcher per object wishes receive number of notifications changes in number of objects.
what it:
- you can have 1
observevalueforkeypath
per class, may want observe several things. natural next thought "hey maybe can pass selector" - oh, isn't possible pass multiple arguments via
performselector
unless wrapper objectsnsnotification
used. wants clean wrapper objects. - overriding
observevalueforkeypath
when superclass uses kvo makes generic approaches hard -- have know notifications pass super class , keep. - who wants re-implement same generic selector-based
observevalueforkeypath
in every object anyway? better once , reuse it.
a nice variation might add field id additionalcontext
kvodispatcher , have additionalcontext object passed in objc_msgsend
call. useful use stash ui object needs updated when observed data changes. perhaps nsarray.
Comments
Post a Comment