удобство создания подклассов - PullRequest
1 голос
/ 12 февраля 2012

Если у меня есть суперкласс с удобным конструктором следующим образом (с использованием ARC):

+(id)classA {
    ClassA *foo = [[ClassA alloc] init];

    return foo;
}

Если я подкласс ClassA, с классом с именем ClassB, и я хочу переопределить удобный конструкторверно следующее:

+(id)classB {
    ClassB *foo = [ClassA classA];

    return foo;
}

(Предположим, что я не могу вызвать alloc и init для ClassB).

Спасибо!

Ответы [ 2 ]

3 голосов
/ 12 февраля 2012

Метод класса передается self точно так же, как метод экземпляра, только в случае метода класса значение self является экземпляром Class. Поэтому измените ваш classA метод на:

+ (id) classA
{
   return [[self alloc] init];
}

(Это просто определение new, которое вы наследуете от NSObject. Соглашение: newX возвращает сохраненную ссылку, в то время как classnameX возвращает автоматически освобожденную ссылку. При использовании ARC разница действительно спорная, но я пойду с newX сам.)

Теперь, если ClassB является подклассом ClassA, тогда [ClassB classA] вызовет classA с self, равным ClassB, и вы получите alloc и init ClassB экземпляр.

2 голосов
/ 12 февраля 2012

Нет, это не правильно, поскольку он выделяет, инициирует и возвращает ClassA, а не ClassB. Единственный способ сделать это - не использовать ClassA явно:

+ (id) classA
{
    return [[self alloc] init];
}

Конечно, вы также можете использовать старомодный new для этого:

ClassB *myB = [ClassB new];

FWIW, если я захочу сделать больше, чем просто выделить и инициализировать, а мой класс называется Gadget, тогда я сделаю что-то вроде:

+ (id) gadgetWithNumber: (int) num
{
    return [[self alloc] initWithNumber: num];
    // or without ARC:
    // return [[[self alloc] initWithNumber: num] autorelease];
}

Конечно, это предполагает, что в моем классе есть метод initWithNumber:.

...