KingPolygon
KingPolygon

Reputation: 4755

iOS: How to make factory method work with subclassing

I have a class of type Matrix which I'd like to subclass. Let's call my subclass Column. I'd like to add new properties to my subclass as well. I love factory methods, and don't like to repeat code, so I create a factory method in my subclass which calls its superclass' factory method when initializing an object.

The problem is that if I create an instance of my Column class, and call a property only found in Column, I get an error, because my Column class' factory method which calls my Matrix class' factory method is returning an instance of type Matrix instead of Column or whatever subclass calls it. I understand why this happens, but I'm not sure how to fix this.

I've read the following article on factory methods, and know that instead of using [[Matrix alloc] init]; I should be using [[self alloc] init];. The problem is I'm not sure how I'd access my instance variables like matrix, rows and freeData which I define in my header as follows:

@interface Matrix : NSObject <NSCoding, NSCopying> {

    @public     double  *matrix;
    @public     int     rows;
    @public     int     columns;
    @private    BOOL    freeUpData;
}

Here's the factory method I need help in. How can I rewrite it so it can access my instance variables, and also work with subclassing (and not only return a Matrix instance).

+ (instancetype)matrixFromArray:(double *)arr Rows:(int)m Columns:(int)n Mode:(refMode)mode
{
    Matrix *mt = [[Matrix alloc] init];
    if (mode == YCMCopy) {

        double *new_m = malloc(m*n*sizeof(double));
        memcpy(new_m, arr, m*n*sizeof(double));
        mt->matrix = new_m;
        mt->freeData = YES;
    }

    else {
        mt->matrix = arr;
        mt->freeData = NO;
    }

    if (mode != YCMWeak) {
        mt->freeData = YES;
    }

    mt->rows = m;
    mt->columns = n;

    return mt;
}

Upvotes: 0

Views: 214

Answers (1)

oxigen
oxigen

Reputation: 6263

You always create Matrix instance but you need to create instance of current class

+ (instancetype)matrix
{
    Matrix *mt = [[self alloc] init];
....
    return mt;
}

And if you do that

[Matrix matrix] will return Matrix object

[Column matrix] will return Column object

Upvotes: 2

Related Questions