Как создать экземпляр класса в 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 или его подкласса, чтобы вы могли инициализировать свой класс