Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Shallow Copy vs Deep Copy

    Hi

    We're using SmartClient 7.0rc2 and have come across the problem identified here

    http://forums.smartclient.com/showpost.php?p=391&postcount=2

    We tend to use the addProperties method to build out our classes and then use the create method to create instances.

    Code:
    isc.defineClass("AccountListMembers", isc.ListGrid).addProperties({
        fields:[
            {name:"accountCode", width:'33%'},
            {name:"accountDesc", width:'*'},
            {name:"accountType", width:'33%', align: 'left'}
        ] 
    });
    
    var availableAccounts = isc.AccountListMembers.create();
    var selectedAccounts = isc.AccountListMembers.create();
    isc.HLayout.create({members: [availableAccounts, selectedAccounts]});
    These instances then end up sharing the same instance the fields array defined on the class with undesired consequences.

    The post referenced above suggests that there might be a change that would help with this problem (perhaps the create method could create deep copies of collections found on the prototype). I was wondering if there have been changes to the create or perhaps you could suggest how we should be doing this kind of thing.

    #2
    What 8.0 does is detect and warn about this, and also give you an attribute listGrid.defaultFields which you can use to define fields at the class level which are automatically duplicated per instance. But you can do the same thing yourself by just creating the fields in initWidget() rather than defining them in an Object passed to addProperties.

    Comment


      #3
      Thanks for your prompt response.

      Yes we can manually clone the fields array

      Code:
      isc.defineClass("AccountListMembers", isc.ListGrid).addProperties({
          defaultFields:[
              {name:"accountCode", width:'33%'},
              {name:"accountDesc", width:'*'},
              {name:"accountType", width:'33%', align: 'left'}
          ],
      
          initWidget: function() {
              this.fields = isc.clone(this.defaultFields); /* Not needed for SC 8*/
              this.Super("initWidget", arguments);
          }
      });
      
      var availableAccounts = isc.AccountListMembers.create();
      var selectedAccounts = isc.AccountListMembers.create();
      isc.HLayout.create({members: [availableAccounts, selectedAccounts]});
      but this means going through our many classes and making this change, not only for the fields property but also for any other arrays or complex types with initial values.

      I guess I was hoping for something within the create method that would detect arrays (and other complex types) and automatically create deep copies on the instance. Do you think such a facility would be useful? If you don't plan on doing this, I guess we'll have to do it ourselves, either by using the above technique or maybe in the base Class.createRaw method

      Code:
          createRaw : function () {
              if (!this.initialized()) this.init();
      
      	// create a new instance based on the class's instanceProtoype
      	var newInstance = new this._instancePrototype._instanceConstructor();
      
              // install the appropriate namespace on the instance
              newInstance.ns = this.ns;
              
              return deepCopy(newInstance);
          },
      where the deepCopy method makes copies of any array or complex type property on the instance.

      Comment


        #4
        We considered this. You definitely would not want to do this at the instance level as you've shown (gigantic slowdown). It could make sense to do in Class.addProperties(), but would still be a large slowdown in framework init time, unnecessarily creating copies of many properties.

        If you wanted to do anything here, we'd recommend checking for complex properties in addProperties() and warning about them, and offering a separate API for explicitly adding complex properties that bypasses the warning. But you'll want to turn the checking off for a production application.

        Comment


          #5
          Shallow Copy vs Deep Copy

          [FONT=verdana][SIZE=3]Shallow copying is creating a new object and then copying the non static fields of the current object to the new object. If the field is a value type, a bit by bit copy of the field is performed. If the field is a reference type, the reference is copied but the referred object is not, therefore the original object and its clone refer to the same object. A shallow copy of an object is a new object whose instance variables are identical to the old object. In .Net shallow copy is done by the object method MemberwiseClone().

          Deep copy is creating a new object and then copying the non-static fields of the current object to the new object. If a field is a value type, a bit by bit copy of the field is performed. If a field is a reference type, a new copy of the referred object is performed. A deep copy of an object is a new object with entirely new instance variables, it does not share objects with the old. While performing Deep Copy the classes to be cloned must be flagged as [Serializable].

          More....[/SIZE][/FONT]

          http://net-informations.com/faq/net/...-deep-copy.htm

          Balmer

          Comment

          Working...
          X