Как создать экземпляр класса в Objective-C, который не наследуется от NSObject

Учитывая это:

Person.h:

@interface Person 
{
}
- (void) sayHello;
@end

Person.m:

#import "Person.h"

@implementation Person 

- (void)sayHello 
{
    printf("%s", "Steve");
}

@end

Как вы создаете экземпляр Person? Я пробовал это:

Person *p = [Person new];

Это не работает, и это:

Person *p = [Person alloc];

[ОБНОВЛЕНИЕ]

Я забыл сказать, я уже пробовал наследовать от NSObject, новый и alloc работает. Мне просто интересно, можем ли мы создать экземпляр класса, который не наследуется от NSObject?

Ответы

Ответ 1

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

Управление памятью с подсчетом ссылок также будет приятным (retain/release); это фактически часть протокола NSObject. Вы можете принять протокол и реализовать эти методы тоже.

Для справки вы можете посмотреть класс Object, который является корневым классом ObjC, например NSObject, который Apple предоставляет в его хранилище с открытым исходным кодом для среды выполнения Objective-C:

@implementation Object 

// Snip...

+ alloc
{
    return (*_zoneAlloc)((Class)self, 0, malloc_default_zone()); 
}

// ...

- init
{
    return self;
}

// And so on...

Как говорится, вы должны думать о NSObject как неотъемлемой части времени выполнения ObjC. Там мало, если есть какая-то причина для реализации собственного корневого класса за пределами любопытства, исследования или экспериментирования (что, однако, не должно быть обескуражено вообще).

Ответ 2

Вы должны:

  • Наследовать от NSObject,
  • Сделайте класс "бедных" со своими собственными маллоками и т.д., или
  • Используйте Objective-C ++ и создайте класс С++.

Конечно, ни один из двух других не вписывается в управление хранилищем Objective-C, а их протоколы вызовов и т.д. - разные.

Ответ 3

Существует (очень вероятно) отсутствие веских причин не наследовать от NSObject, но есть много веских причин для этого.

Мне было бы интересно узнать, почему вы не хотите наследовать NSObject. Я предполагаю, что это связано с недостатком знаний, а не с реальной потребностью.

Но даже не зная этой причины: не делай этого. Это так сложно сделать так хорошо, что он по-прежнему отлично справляется с другими классами Objective-C, что практически невозможно.

В любом случае, вы создаете объекты таким образом, чтобы скрыть то, что действительно сделано. Хотя в Java вы обычно создаете экземпляры с помощью метода конструктора по умолчанию new, в Objective-C вы создаете экземпляр, вызывая alloc в классе, а затем init в экземпляре:

Person *aPerson = [[Person alloc] init];

(Можно просто использовать Person new, но я не сделал бы этого, потому что он скрывает то, что действительно сделано от вас)

Вы реализуете свой класс таким образом, чтобы вы наследовали NSObject, а затем, при необходимости, напишите свой собственный метод init.

Если вы хотите войти в консоль, используйте NSLog:

NSLog(@"Hello %@", @"Steven");

(@"" является специальным конструктором для NSString. Строки в Objective-C не являются байтовыми массивами, а объектами.)

Ответ 4

вы не можете..

Alloc и new..copy init все эти методы определены в NSObject..

Вы также не можете создать свой собственный, так как Apple не предоставляет класс реализации NSObject.. так что вам нужно наследовать от NSObject или его подкласса, чтобы вы могли инициализировать свой класс