Re: Persistance
Re: Persistance
- Subject: Re: Persistance
- From: "Erik M. Buck" <email@hidden>
- Date: Wed, 10 Oct 2001 02:24:29 -0500
Regarding partially initialized objects:
When decoding an object that was encoded as properties, several things can
go wrong. An essential property may be missing or have the wrong type. A
type may be specified in the properties file that does not exist in the
application doing the decoding. Finally, property names sometimes change
(perhaps to correct spelling errors) so conversions may be necessary.
Too many properties are not a problem. Properties that are not requested
are ignored.
- If an essential property is missing:
First, not all properties are essential. Classes should usually be able to
cope with nil instance variables and the like. However, if a property is
essential and is missing, the following things happen:
First, some decoding methods allow the specification of a default value to
use if the requested property is not available. This is handy if the
default value is nil or 5.3 or whatever.
When it is not reasonable to specify a default value (perhaps because
creating the default value is an expensive waste if the default value is not
needed) or no default value makes sense, then decoding methods that don't
specify a default value can be used. When they are used, if a property is
missing or of the wrong type then a method -(BOOL)provideDefaultValue:(void
*)storage forPropertyDecoder:(EMBPropertyDecoder *)aDecoder
property:(NSString *)propertyKey is called and can be implemented to
allocate expensive default values and/or try to decipher a value from other
properties that are available. If there is really no viable default value
then -provideDefaultValue:forPropertyDecoder:property: should be implemented
to either raise an exception or return NO which causes an exception to be
raised by the property decoder.
- If a property exists but has the wrong type (as can happen with hand
edited files) the following things happen:
Reasonable type conversions are attempted. Reasonable includes float to int
and int to float and int to BOOL and the strings YES, TRUE, NO, FALSE,
false, etc. to BOOL and so on. If no reasonable type conversion is possible
then the situation is handled the same as if the property is
issing. -provideDefaultValue:forPropertyDecoder:property: can be
implemented to attempt more type conversions or supply a default value or
raise an exception or return NO.
- A type, usually a class name, is specified in the properties file, but the
decoding application does not know the type.
First, all of the standard hooks in the Objective-C run-time are available.
The decoder uses NSClassFromString() which triggers the class loader/handler
in the run-time for unknown classes.
Second, -decoderClassForClass: works just like the similar method for
NSCoder.
Third, if the decoder still has no valid type (probably the specified class
is resolved as Nil) then an exception is raised. It does not work to have
a -(Class)provideClassNamed:forPropertyDecoder: method because this problem
typically occurs when an old version of an application reads a property file
written by a newer version. The old version of the application probably can
not do anything sensible without loosing or corrupting data stored in the
property file. Remember, extra properties are harmless regardless of their
type. The problem only arises if a _requested_ property has an unknown
type.
The best way to avoid this problem is to change the property name if the
type of the property changes in an incompatible way from one version to
another.
- A property name has changed from one version of the application to
another, but they really are the same property. This has happened in our
code because miss-spellings in property named were "fixed".
First, a dictionary or synonyms can be set before decoding starts. The keys
in the dictionary are the old (miss-spelled) property names and the values
are the new names. Whenever a property name that has a synonym is
encountered, the new name is used.
Second, if a property can not be found because of a name change that is not
handled by synonyms, the
-provideDefaultValue:forPropertyDecoder:property: is called and can look
for a property with the old name or supply a default or raise an exception
or return NO.
Also, -awakeFromPropertyDecoder: is called for every decoded object, and it
can be implemented to return a different instance.