2010-02-02 3 views
8

Возможно ли создать класс без метода init, чтобы заставить всех вызывающих пользователей создать объект с использованием фабричного метода?Создание класса без метода init (Objective-c)

+1

Возможно, было бы полезно объяснить, чего вы на самом деле хотите достичь. – Chuck

+1

Кажется, для меня совершенно законный вопрос, который не нуждается в контексте, чтобы иметь смысл. Существует множество причин, по которым у вас будет класс, который не нуждается в какой-либо конкретной настройке. –

+0

@Squeegy: Чак был прав - исходный вопрос должен был объяснить, что я хотел выполнить. Из ответов ниже ясно, что некоторые из респондентов не были уверены в том, что я просил (я фактически поддержал комментарий Чака) – Casebash

ответ

5

Итак, вы хотите убедиться, что ваш класс никогда не инициализирован с использованием -init, правильно? Вы не можете сделать точно, что вы хотите сделать, но вы можете приблизиться.

Поскольку вы наследуете NSObject, у вас есть метод init, и вы ничего не можете сделать, чтобы предотвратить его вызов.Тем не менее, вы можете переопределить инициализации для этого:

- (id)init 
{ 
    [self dealloc]; 
    @throw [NSException exceptionWithName:@"MyExceptionName" reason:@"Reason" userInfo:nil]; 
    return nil; 
} 

Таким образом, в любое время кто-то называет свой метод -init, он убивает объект, поэтому с практической точки зрения, ваш метод инициализации довольно много не-отозваны.

+0

Имеет ли объект-c нечто вроде не реализованного исключения? – Casebash

+0

На самом деле вам не нужно возвращать в конце - он никогда не будет достигнут – Casebash

+1

Объектив-C является исключением-недружественным, поскольку он может вызывать утечку объектов повсюду (поскольку их вызовы 'release' никогда не могут быть достигнуты) , Если вы не используете собранную мусором время выполнения, как ни грустно это звучит, вам лучше не использовать их. – zneak

0

Несомненно. В Objective-C нет фактических конструкторов. init Методы типа обычно используются для инициализации класса в том же духе, что и конструктор, но они просто «нормальный» метод (нет ничего особенного в них, например, с конструкторами Java).

Тем не менее, если ваш класс не делает не инициализации для его экземпляров, вы, вероятно, хотите , чтобы иметь какой-то init метода.

0

NSObject использует метод init, который делает то, что он делает. Если вашему классу нечего настраивать при его создании, просто не переопределяйте метод -(id)init, предоставляемый NSObject. Но вы все еще называете это, когда создаете экземпляр.

1

Зависит. Если у вас наследуется класс от NSObject, он будет иметь унаследованный метод init (который ничего не делает для ваших переменных экземпляра). Таким образом, в этом смысле, даже если вы действительно не хотели иметь метод init, у вас, скорее всего, есть его. Поэтому, если ваш вопрос: «Нужно ли мне реализовать тривиальный метод init?», Ответ «нет, вам не нужно». Однако, если ваш вопрос: «Нужно ли мне называть метод init, если я его не переопределял?», Тогда ответ «да, вы делаете». Что бы вы ни делали с подклассами NSObject, в какой-то момент вам все равно нужно вызвать init после создания объекта. Таков образ жизни.

Это, пожалуйста, вы скорее всего хотите, чтобы метод init, если ваша инициализация объекта не требует ничего, кроме обнуления всего объекта.

В противном случае, если вы решите не наследоваться от NSObject или любого из его подклассов и просто наследуют из ничего, что явно плохая идея, потому что от того, как NSObject класса занимается все время выполнения ObjC должен сделать а требования довольно высоки, тогда вы, возможно, окажетесь без init метода вообще. Но серьезно, не пробуйте это дома.

4

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

@implementation MyClass 

- (id) init 
{ 
    // Still have to make sure the runtime has initialised everything for "self" 
    self = [super init]; 
    if (!self) return nil; 
    [self release]; // some say you should use [super dealloc] 
    [super doesNotRecognizeSelector:_cmd]; 
    return nil; 
} 

@end 

вы вызываете super «s doesNotRecognizeSelector:, потому что вы можете реализовать свое поведение для непризнанных селекторов твой класс.

+0

Почему мы не можем просто вернуть нуль? – Casebash

+0

О, если они были выделены, мы должны освободить – Casebash

+0

Вы можете просто вернуть нуль, и это, вероятно, лучший выбор здесь. – Chuck

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