flex中的uid(analogy to java hashcode)

1. Be careful when defining uid property in your class
if you defined a uid property in your class (in regardless of its type, no matter what type it is), you will certainly find something wrong in your application soon, such as you cannot select some rows in List control and nodes in Tree control, why do we have this kind of strange issue when we don’t see any compiler error and runtime error, the reason is because flex data provider controls use a unique identifier (UID) to track data items, flex can automatically create and manage UIDs, but if you own class has uid property, flex will use the class defined uid, when the value of uid property in your object is not unique, then you will get above described strange issue. 
By the way, you can use logger. debug ("selected object's uid:"+UIDUtil.getUID(selectedObject)); to check the uid value of your selected object.
Please see the following section for more details about uid in flex.

2. Data providers and the uid property
Flex data provider controls use a unique identifier (UID) to track data items. Flex can automatically create and manage UIDs. However, there are circumstances when you must supply your own uid property by implementing the IUID interface, and there are circumstances when supplying your own uid property improves processing efficiency.
Because the Object and Array classes are dynamic, you normally do not do anything special for data objects whose items belong to these classes. However, you should consider implementing the IUID if your data object items belong to custom classes that you define.
Note: When Flex creates a UID for an object, such as an item in an ArrayCollection, it adds the UID as an mx_internal_uid property of the item. Flex creates mx_internal_uid properties for any objects that are dynamic and do not have bindable properties. To avoid having Flex create mx_internal_uid properties, the object class should do any of the following things: have at least one property with a [Bindable] metadata tag; implement the IUID interface; or have a uid property with a value.

If Flex must consider two or more different objects to be identical, the objects must implement the IUID interface so that you can assign the same uid value to multiple objects. A typical case where you must implement the IUID interface is an application that uses paged collections. As the cursor moves through the collection, a particular item might be pulled down from the server and released from memory repeatedly. Every time the item is pulled into memory, a new object is created to represent the item. If you need to compare items for equality, Flex should consider all objects that represent the same item to be the same "thing."
More common than the case where you must implement the IUID interface is the case where you can improve processing efficiency by doing so. As a general rule, you do not implement the IUID interface if the data provider elements are members of dynamic classes. Flex can automatically create a uid property for these classes. There is still some inefficiency, however, so you might consider implementing the IUID interface if processing efficiency is particularly important.

In all other cases, Flex uses the Dictionary mechanism to manage the uid, which might not be as efficient as supplying your own UID.
The IUID interface contains a single property, uid, which is a unique identifier for the class member, and no methods. Flex provides a UIDUtil class that uses a pseudo-random-number generator to create an identifier that conforms to the standard GUID format. Although this identifier is not guaranteed to be universally unique, it should be unique among all members of your class. To implement a class that uses the UIDUtil class, such as a Person class that has fields for a first name, last name, and ID, you can use the following pattern:
package {
    import mx.core.IUID;
    import mx.utils.UIDUtil;

    [Bindable]
    public class Person implements IUID {
        public var id:String;
        public var firstName:String;
        public var lastName:String;
        private var _uid:String;

        public function Person() {
            _uid = UIDUtil.createUID();
        }

        public function get uid():String {
            return _uid;
        }

        public function set uid(value: String):void {
            // Do nothing, the constructor created the uid.
        }
    }
}

You do not need to use the UIDUtil class in a case where the objects contain a uniquely-identifying field such as an employee ID. In this case, you can use the person's ID as the uid property, because the uid property values uniquely identify the object only in the data provider. The following example implements this approach:
package
{
    import mx.core.IUID;

    [Bindable]
    public class Person implements IUID {
        public var employee_id:String;
        public var firstName:String;
        public var lastName:String;

        public function get uid(): String {
            return employee_id;
        }

        public function set uid(value: String): void {
            employee_id=value;
        }
    }
}

Note: Object cloning does not manage or have a relationship with UIDs, so if you clone something that has an internal UID you must also change that internal UID. UIDs are stored on mx_internal_uid only for dynamic Objects. Instances of data classes that implement IUID store their UIDs in a uid property, so that is the property that must be changed after cloning.


3. Some guys who suffering from this problem
This has cost me a lot of time. If you implement a custom ValueObject which has a public property called uid (which was actually an user id in my app) and all of the items in the list have the same user id this will lead into serious problems. There should be at least a compiler warning or something that assigning uid can lead to problems if it isn't unique for all items. I searched about 2 hours for this entry.

An alternative to implementing iuid in order to have multiple objects as equal, is to check for the existence of an object in memory before instantiating it.  A simple factory method that updates instead of creates when appropriate will do the job.  Often a primary key for the database table will serve the purpose to identify the equal object.
 
It might be useful to use a database primary key as a light weight iuid, but I have not yet tried this because the value of my primary keys change from a negative number to a positive one when the row is inserted in the database.

你可能感兴趣的:(Flex,HashCode,uid,dataprovider,唯一)