Методы класса, которые создают новые экземпляры

Помимо стандарта [[MyClass alloc] init] шаблон, некоторые объекты построены из статических методов, таких как MyClass *obj = [MyClass classWithString:@"blabla"]

Согласно широко распространенным руководствам по управлению памятью (включая Apple), вы несете ответственность только за освобождение объектов, которые вы alloc,

Кто-нибудь может предоставить мне шаблон для таких методов? Как вы возвращаете выделенный объект ([self alloc]; return self;возможно)? Как вы убедитесь, что он будет выпущен?

4 ответа

Решение

Это классовые методы, а не статические 1. Этот конкретный тип, создающий автоматически выпущенные объекты, может называться "фабричными методами" (ранее также "удобными конструкторами"), и они обсуждаются в Концепциях в Руководстве ObjC. Они идут примерно так:

+ (instancetype)whatsisWithThingummy: (Thingummy *)theThingummy {
    return [[self alloc] initWithThingummy:theThingummy];
}

куда Whatsis это ваш класс, и Thingummy это другой класс, который использует ваш класс.

Если вы не компилируете с ARC, соглашение заключается в autorelease экземпляр, прежде чем вернуть его.

instancetype ключевое слово было введено Clang для таких методов; в сочетании с self (который сам является объектом класса 2 в методе класса), он позволяет корректно вести себя подклассом: метод создает экземпляр класса, который получил сообщение. 3 instancetype позволяет компилятору выполнять более строгую проверку типов, чем id,

Иллюстрация этого использования в подклассах из фреймворка: +[NSString stringWithFormat:] возвращает NSString экземпляр, тогда как +[NSMutableString stringWithFormat:], возвращает экземпляр подкласса NSMutableString без NSMutableString требуется явно переопределить метод.

Как обсуждалось в документе [ Основы ][1], существуют другие способы использования этих заводских методов, такие как доступ к одноэлементному протоколу или оценка необходимого выделения памяти перед его выполнением (возможно, но менее удобно при использовании стандартного метода). alloc / init пара).


1 "Статические методы" в Java или C++, "методы класса" в Objective-C. В ObjC нет статических методов

2 В то время как в методе экземпляра self разумно, ссылка на экземпляр.

3 Раньше нравились обычные методы инициализации ( initWith... ), вы бы использовали id как тип возвращаемого значения. Использование определенного имени класса излишне заставляет подклассы переопределять метод.

Объекты, возвращаемые фабричными методами, должны быть автоматически освобождены, то есть они будут очищены при сливе соответствующего пула автоматического выпуска. Это означает, что вы не являетесь владельцем возвращенных объектов, если вы copy или же retain их. Ниже приведен пример фабричного метода:

+ (id)myClassWithString:(NSString *)string {
    return [[[MyClass alloc] initWithString:string] autorelease];
}

Эти методы просто возвращают автоматически выпущенную версию объекта.

+(MyClass*)class
{
  MyClass* object = [[MyClass alloc] init];
  return [object autorelease];
}

Современный способ сделать это с ARC и последним компилятором:

+ (instancetype) myClassWithString:(NSString *)string {
     return [[MyClass alloc] initWithString:string];
}
  • Нет необходимости в автоматическом выпуске с ARC.
  • instancetype обеспечивает лучшую проверку времени компиляции, делая возможным создание подклассов.
Другие вопросы по тегам