[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