2015-02-24 2 views
1

У меня возникли проблемы с пониманием использования [[self alloc] init] при написании заводских методов. Я понимаю, что фабричные методы - это удобные методы для создания экземпляров класса, и что они делают alloc, init и autorelease для вас. Я вижу, как это формируется, например, в объявлении свойства NSArray с заводским методом arrayWithArray: или array и т. Д., Чтобы вызвать его. Я, очевидно, вижу, как это отличается от прямого (явного) вызова alloc и init.Использование [[self alloc] init] при написании заводских методов

Моя проблема заключается в том, что я не понимаю фабричные методы на более глубоком уровне. Я наткнулся на объяснение в Интернете, который сказал, вместо вызова alloc и init в явном виде, метод класса завод может быть использован в основном инкапсулирует что-то вроде этого:

+(instancetype)createWithString:(NSString *)string 
{ 
    return [[self alloc] initWithString:string]; 
} 

Но как instancetype и [self alloc] эффективно позволяют подклассы использовать метода фабрики класса?

+2

Я не уверен, что вы просите. Означает ли [методы класса, которые создают новые экземпляры] (http://stackoverflow.com/q/5987969) что-нибудь для вас? –

+1

Этот подход не имеет проблем с подклассами, поскольку 'self', если он динамически решен во время выполнения и будет« указывать »на« активный класс ». 'NSArray',' NSNumber', 'NSString' являются специальными случаями, называемыми кластерами классов ([официальный doc] (https://developer.apple.com/library/ios/documentation/General/Conceptual/CocoaEncyclopedia/ClassClusters/ClassClusters.html)) – tkanzakic

+0

@Josh: Да, это действительно полезно. Я просто прочитал эту страницу и нашел ее очень полезной: http://qualitycoding.org/factory-method/ – cheznead

ответ

5
  1. instancetype это ключевое слово, которое говорит «тип возврата этого метода является типом класса, что этот метод был вызван» (или подкласс). Итак, если вы звоните [Baseclass createWithString:], тип возврата - Baseclass *. Однако предположим, что вы создаете подкласс, который делает не переопределить этот метод. Если вы звоните [Subclass createWithString:], тип возврата - Subclass * (не Baseclass *).

  2. Когда класс получает сообщение, self указывает на объект Class. Поэтому при вызове [Baseclass createWithString:], self укажет на объект Baseclass. Однако при вызове [Subclass createWithString:] self будет указывать на Subclass, поэтому, если Subclass определяет свои собственные методы alloc или initWithString: (то есть, он их переопределяет), вместо этого будут вызываться его версии.

+0

Спасибо, очень ясный и лаконичный. – cheznead

Смежные вопросы