iosobjective-cnsmutabledata

How to subclass NSMutableData


I am trying to subclass NSMutableData to add the ability to subdata without copying. Here is code

@interface myMutableData : NSMutableData

- (NSData *)subdataWithNoCopyingAtRange:(NSRange)range;

@end

@interface myMutableData()

@property (nonatomic, strong) NSData *parent;

@end

@implementation myMutableData

- (NSData *)subdataWithNoCopyingAtRange:(NSRange)range
{
    unsigned char *dataPtr = (unsigned char *)[self bytes] + range.location;

    myMutableData *data = [[myMutableData alloc]     initWithBytesNoCopy:dataPtr length:range.length freeWhenDone:NO];

    data.parent = self;

    return data;
}

@end

But the problem is when I try to instantiate myMutableData, I got this error

"-initWithCapacity: only defined for abstract class.  Define -[myMutableData initWithCapacity:]!'"

Why? So inheritance does not work? Thanks


Solution

  • This calls for a category. However, a category cannot by default have properties and instance variables. Hence you need to #import <objc/runtime.h> and use associated objects to get and set value of parent.

    @interface NSMutableData(myMutableData)
    
    - (NSData *)subdataWithNoCopyingAtRange:(NSRange)range;
    
    @property (nonatomic, strong) NSData *parent;
    
    @end
    
    @implementation NSMutableData(myMutableData)
    
    - (NSData *)subdataWithNoCopyingAtRange:(NSRange)range
    {
        unsigned char *dataPtr = (unsigned char *)[self bytes] + range.location;
    
        NSMutableData *data = [[NSMutableData alloc]     initWithBytesNoCopy:dataPtr length:range.length freeWhenDone:NO];
        data.parent = self;
        return data;
    }
    
    -(NSData*)parent
    {
        return objc_getAssociatedObject(self, @selector(parent));
    }
    
    -(void)setParent:(NSData *)parent
    {
        objc_setAssociatedObject(self, @selector(parent), parent, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    @end