[Biococoa-dev] mass calculator bug
Alexander Griekspoor
mek at mekentosj.com
Sat Aug 28 06:24:40 EDT 2004
Ha Koen,
This is because our custom object doesn't support the copying protocol
(see NSCopying in documentation). And now that we're busy anyway, let's
add the very similar NSCoding as well... [DISCLAIMER: typed in mail
and not tested]
So we start with the first interface line in the BCSequence header:
@interface BCSequence : NSObject {
should become:
@interface BCSequence : NSObject <NSCopying, NSCoding> {
Next we add the following methods to support the protocols:
- (id)copyWithZone:(NSZone *)zone;
- (id)initWithCoder:(NSCoder *)coder;
- (void)encodeWithCoder:(NSCoder *)coder;
Now the implementation:
- (id)copyWithZone:(NSZone *)zone{
BCSequence *copy = [[[self class] allocWithZone: zone] init];
[copy setSequenceType : [self sequenceType ]];
[copy setSequence: [self sequence]];
[copy setSequenceCountedSet: [self sequenceCountedSet]];
[copy setRange: [self range]];
[copy setStartPosition: [self startPosition]];
[copy setEndPosition: [self endPosition]];
return copy;
}
Of course you note one problem here, we haven't implemented a number of
accessors. I already mentioned once that we should for all variables
like Apple advices us to do, and always call the accessors if you want
to change things (instead of directly accessing the variable). This is
one example where this comes in handy. If we don't want to make some
accessors public, we have to @private them so they're invisible outside
the class. Anyway, I leave this up to you guys. An alternative would be
a special init method that takes all variables as input and do
everything in one call.
The implementation for the NSCoding methods:
- (id)initWithCoder:(NSCoder *)decoder{
if(self = [super init]{
if ( [coder allowsKeyedCoding] ) {
sequenceType = [coder decodeIntForKey:@"BCSequenceType"];
sequence = [[coder decodeObjectForKey: @"BCSequence"] retain];
sequenceCountedSet = [[coder decodeObjectForKey:
@"BCSequenceCountedSet"] retain];
range = [[coder decodeObjectForKey: @"BCSequenceRange"] rangeValue];
startPosition = [coder
decodeIntForKey:@"BCSequenceStartPosition"];
endPosition = [coder
decodeIntForKey:@"BCSequenceEndPosition"];
} else {
[coder decodeValueOfObjCType:@encode(int) at: &sequenceType];
sequence = [[coder decodeObject] retain];
sequenceCountedSet = [[coder decodeObject] retain];
[coder decodeValueOfObjCType:@encode(NSRange) at: &range];
[coder decodeValueOfObjCType:@encode(int) at:
&startPosition];
[coder decodeValueOfObjCType:@encode(int) at: &endPosition];
}
}
return self;
}
In BCMassCalculator, InitWithSequence, change:
> sequence = [seq copy]; <--------- error
to sequence = [seq copyWithZone: [self zone]]; // I believe this is
more efficient memory wise
- (void)encodeWithCoder:(NSCoder *)coder{
if ( [coder allowsKeyedCoding] ) {
[coder encodeInt: sequenceType forKey: @"BCSequenceType"];
[coder encodeObject: sequence forKey: @"BCSequence"];
[coder encodeObject: sequenceCountedSet forKey:
@"BCSequenceCountedSet"];
[coder encodeObject: [NSValue valueWithRange: range] forKey:
@"BCSequenceRange"];
[coder encodeInt: startPosition forKey:
@"BCSequenceStartPosition"];
[coder encodeInt: endPosition forKey: @"BCSequenceEndPosition"];
} else {
[coder encodeValueOfObjCType:@encode(int) at:&sequenceType]; //
Not sure if it should be @encode(BCSequenceType)
[coder encodeObject: sequence];
[coder encodeObject: sequenceCountedSet];
[coder encodeValueOfObjCType:@encode(NSRange) at:&range];
[coder encodeValueOfObjCType:@encode(int) at:&startPosition];
[coder encodeValueOfObjCType:@encode(int) at:&endPosition];
}
return;
}
Subclasses like BCSequenceDNA need to override this method, first call
[super copyWithZone: zone] and then add the subclass specific
variables. The same holds true for initWithCoder and encodeWithCoder
(call [super encodeWithCoder:coder] for instance).
One note, perhaps we should actually adhere to the
MutableCopyingProtocol as our objects are mutable, but I'm not sure
(and don't see many differences).
Cheers,
Alex
Op 28-aug-04 om 6:12 heeft Koen van der Drift het volgende geschreven:
> Hi,
>
> To test my mass calculator code, I added the following line to the
> demo code:
>
> mw = [theSequence molecularWeight:BCAverage];
>
>
> This causes an error in:
>
>
> @implementation BCMassCalculator
>
> -(id) initWithSequence:(BCSequence *)seq
> {
> if (self = [super init])
> {
> sequence = [seq copy]; <--------- error
> }
>
> return self;
> }
>
>
> the error is:
>
> 2004-08-28 00:08:25.565 demo_app[2490] *** -[BCSequenceDNA
> copyWithZone:]: selector not recognized
>
>
> Anyone have an idea what this means and how to fix it?
>
>
> thanks,
>
> - Koen.
>
> _______________________________________________
> Biococoa-dev mailing list
> Biococoa-dev at bioinformatics.org
> https://bioinformatics.org/mailman/listinfo/biococoa-dev
>
>
*********************************************************
** Alexander Griekspoor **
*********************************************************
The Netherlands Cancer Institute
Department of Tumorbiology (H4)
Plesmanlaan 121, 1066 CX, Amsterdam
Tel: + 31 20 - 512 2023
Fax: + 31 20 - 512 2029
AIM: mekentosj at mac.com
E-mail: a.griekspoor at nki.nl
Web: http://www.mekentosj.com
The requirements said: Windows 2000 or better.
So I got a Macintosh.
*********************************************************
*********************************************************
** Alexander Griekspoor **
*********************************************************
The Netherlands Cancer Institute
Department of Tumorbiology (H4)
Plesmanlaan 121, 1066 CX, Amsterdam
Tel: + 31 20 - 512 2023
Fax: + 31 20 - 512 2029
AIM: mekentosj at mac.com
E-mail: a.griekspoor at nki.nl
Web: http://www.mekentosj.com
iRNAi, do you?
http://www.mekentosj.com/irnai
*********************************************************
More information about the Biococoa-dev
mailing list