I have managed to dig myself out of the hole I fell into today, but I would
be grateful if anyone could explain what I did wrong, and how I can avoid it in future. Following the saga reported in another thread, I have developed an MVP triad for drawing graphs, which works in a limited way. In trying to simplify and generalise it, I tried to add another instance variable to my model class. The effect was that, when I next tried to load my main shell, the system generated a walkback with 'end of stream'; it looked as though the loader was going wrong in loading the view resource for my graph MVP triad. I eventually solved this by renaming an existing instance variable and giving its old function to a method local - essentially it was no longer necessary to preserve what was now just an intermediate result. Is there some danger in adding instance variables? - I know I have done it before without problems. The effect is puzzling, because there seems so little connection between the model and the view - is there something in the view resource which depends on the number of instance variables in the model class? I have saved enough intermediate images to be able to reproduce this if necessary, but I don't want to clutter this newsgroup with too much detail. Grateful for any help. Peter Kenny |
Peter,
> I have managed to dig myself out of the hole I fell into today, but I > would be grateful if anyone could explain what I did wrong, and how I > can avoid it in future. > > Following the saga reported in another thread, I have developed an > MVP triad for drawing graphs, which works in a limited way. In trying > to simplify and generalise it, I tried to add another instance > variable to my model class. The effect was that, when I next tried > to load my main shell, the system generated a walkback with 'end of > stream'; it looked as though the loader was going wrong in loading > the view resource for my graph MVP triad. I eventually solved this by > renaming an existing instance variable and giving its old function to > a method local - essentially it was no longer necessary to preserve > what was now just an intermediate result. Is there some danger in > adding instance variables? - I know I have done it before without > problems. The effect is puzzling, because there seems so little > connection between the model and the view - is there something in the > view resource which depends on the number of instance variables in > the model class? > > I have saved enough intermediate images to be able to reproduce this > if necessary, but I don't want to clutter this newsgroup with too > much detail. Most likely you have a #defaultModel class method for your graph view that installs an instance of your model into any instance of the graph view that is created (e.g. the one created by the view composer). When you save your view as a resource this default model is saved out too (in STB format). This is the case even though, when the view is reloaded from the resource to be attached to its eventual presenter, another model object (presumably of the same class) will be installed. To get around this, you have two options: 1) Whenever you change the instance variable layout of your model class, you should write an STB upgrade procedure for old instance of the class so they can be loaded in the new format. This involves writing two class side methods, #stbVersion and #stbConvertFrom:. Take a look at the help: http://www.object-arts.com/Lib/EducationCentre4/htm/convertingstbdataaft erinstancelayoutchanges.htm and dsearch for these in the image to see how they are used (try looking at Package). 2) Alternatively you could make your view accept a nil model and make #defaultModel for the view answer nil too. This would mean that the only instance of your model that would get created woould be the one by the presenter. Hope this helps. Andy Bower Dolphin Support www.object-arts.com |
"Andy Bower" <[hidden email]> wrote in message
news:[hidden email]... > Peter, > > Most likely you have a #defaultModel class method for your graph view > that installs an instance of your model into any instance of the graph > view that is created (e.g. the one created by the view composer). When > you save your view as a resource this default model is saved out too > (in STB format). This is the case even though, when the view is > reloaded from the resource to be attached to its eventual presenter, > another model object (presumably of the same class) will be installed. > > To get around this, you have two options: > > 1) Whenever you change the instance variable layout of your model > class, you should write an STB upgrade procedure for old instance of > the class so they can be loaded in the new format. This involves > writing two class side methods, #stbVersion and #stbConvertFrom:. Take > a look at the help: > > http://www.object-arts.com/Lib/EducationCentre4/htm/convertingstbdataaft > erinstancelayoutchanges.htm > > and dsearch for these in the image to see how they are used (try > looking at Package). > > 2) Alternatively you could make your view accept a nil model and make > #defaultModel for the view answer nil too. This would mean that the > only instance of your model that would get created woould be the one by > the presenter. > > Hope this helps. > > Andy Bower > Dolphin Support > www.object-arts.com Andy You are right about the default model. I shall try to get round it by the second route if I can - I can't now remember why it's there. Many thanks Peter |
In reply to this post by Andy Bower-3
> To get around this, you have two options:
> > 1) Whenever you change the instance variable layout of your model > class, you should write an STB upgrade procedure for old instance of > the class so they can be loaded in the new format. This involves > writing two class side methods, #stbVersion and #stbConvertFrom:. Take > a look at the help: > > http://www.object-arts.com/Lib/EducationCentre4/htm/convertingstbdataaft > erinstancelayoutchanges.htm > > and dsearch for these in the image to see how they are used (try > looking at Package). > > 2) Alternatively you could make your view accept a nil model and make > #defaultModel for the view answer nil too. This would mean that the > only instance of your model that would get created woould be the one by > the presenter. > > Hope this helps. > > Andy Bower > Dolphin Support > www.object-arts.com Third option: Have a ViewComposer open on the view in question while making changes in the model. Save the view when you're done. Pieter |
"Pieter Emmelot" <[hidden email]> wrote in message
news:[hidden email]... > > To get around this, you have two options: > > Third option: > Have a ViewComposer open on the view in question while making changes in > the model. Save the view when you're done. > > Pieter Pieter - Thanks, this looks brilliantly simple. I tried it, even though I no longer need the extra instance variable. The one odd thing was that, as I pressed 'Accept' for the revised class definition, the system showed a warning: 'Raised signal - end of stream'. However, I saved the new view and loaded my shell with no problems, and an inspector showed that the model has the extra instance variable. So it works! Thanks Peter. |
In reply to this post by Pieter Emmelot-2
"Pieter Emmelot" <[hidden email]> wrote in message
news:[hidden email]... >> To get around this, you have two options: >> >> 1) Whenever you change the instance variable layout of your model >> class, you should write an STB upgrade procedure for old instance of >> the class so they can be loaded in the new format. This involves >> writing two class side methods, #stbVersion and #stbConvertFrom:. Take >> a look at the help: >> >> http://www.object-arts.com/Lib/EducationCentre4/htm/convertingstbdataaft >> erinstancelayoutchanges.htm >> >> and dsearch for these in the image to see how they are used (try >> looking at Package). >> >> 2) Alternatively you could make your view accept a nil model and make >> #defaultModel for the view answer nil too. This would mean that the >> only instance of your model that would get created woould be the one by >> the presenter. >> >> Hope this helps. >> >> Andy Bower >> Dolphin Support >> www.object-arts.com > > Third option: > Have a ViewComposer open on the view in question while making changes in > the model. Save the view when you're done. > Yes, this is indeed the best approach during development before one has "published" a view resource. It is certainly the method I use. If anyone is wondering why it works, well it is just taking advantage of the normal class schema migration capabilities that are used whenever you modify any other class that has existing instances. This is done by the ClassBuilder, and the effect is that any same named instance variables in the "new" class are preserved (i.e. you can reorder them), and values in deleted instance variables are discarded, and any new instance variables are initialized to nil. This last may mean that you need to partially initialize any existing instances after adding a new instance variable, but this is easily achieved by either a simple #allInstances enumeration, or by using a lazy accessor for the variable. A couple of other useful STB tips are: 1) Never re-order instance variables - add them on the end. If you do this, and you use lazy accessors, you won't need to write an STB conversion method for leaf classes, just increment the stbVersion number. 2) Never delete instance variables - just reserve them for future use. 3) When adding instance variables, reserve a few extra spares. Regards Blair |
Free forum by Nabble | Edit this page |