Методы класса, которые создают новые экземпляры
Помимо стандарта [[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
обеспечивает лучшую проверку времени компиляции, делая возможным создание подклассов.