Использовать Objective-C без NSObject?

Я тестирую простой код Objective-C в Windows (cygwin, gcc). Этот код уже работает в Xcode на Mac. Я хотел бы преобразовать свои объекты в подкласс NSObject (или что-нибудь еще, лол). Возможно ли это и как?

Что у меня есть на данный момент:

// MyObject.h
@interface MyObject

- (void)myMethod:(int) param;

@end

и

// MyObject.m
#include "MyObject.h"

@interface MyObject()
{ // this line is a syntax error, why?
    int _field;
}
@end

@implementation MyObject

- (id)init {
  // what goes in here?
    return self;
}

- (void)myMethod:(int) param {
  _field = param;
}

@end

Что происходит, когда я пытаюсь его скомпилировать:

gcc -o test MyObject.m -lobjc
MyObject.m:4:1: error: expected identifier or ‘(’ before ‘{’ token
MyObject.m: In function ‘-[MyObject myMethod:]’:
MyObject.m:17:3: error: ‘_field’ undeclared (first use in this function)

ИЗМЕНИТЬ Мой компилятор - это cygwin gcc, также есть пакет cygwin gcc-objc:

gcc --version
gcc (GCC) 4.7.3

Я пытался найти это в Интернете и в паре руководств по Objective-C, но каждый пример класса, который я нашел, наследуется от NSObject. Неужели невозможно написать Objective-C без Какао или какой-либо замены Какао, которая предоставляет NSObject?

(Да, я знаю о GNUstep. Я бы предпочел избежать этого, если возможно ...)

ИЗМЕНИТЬ Это работает:

// MyObject.h
@interface MyObject
@end
// MyObject.m
#include "MyObject.h"
@implementation MyObject
@end

Хотя не очень полезно ...


person Alex I    schedule 20.10.2013    source источник
comment
Возможно полезно: stackoverflow.com/ questions / 6203467 /, stackoverflow.com/questions/4295317/ (обратите внимание, что в этом вопросе новый корневой класс по-прежнему реализует протокол NSObject )   -  person user2864740    schedule 20.10.2013
comment
Спасибо! Означает ли это, что невозможно выделить объект даже без использования NSObject? Ах ... какой дурацкий язык. Я не хочу взаимодействовать со средой выполнения или какими-либо библиотеками, я просто хочу запустить полностью автономный, простой фрагмент кода. Думаю, я могу написать это на простом C и просто назвать это файлом .m, ха-ха.   -  person Alex I    schedule 20.10.2013
comment
возможный дубликат Как создать экземпляр класс в Objective-C, который не наследуется от NSObject   -  person jscs    schedule 20.10.2013
comment
NSObject протокол не то же самое, что NSObject. При этом я никогда не пробовал :)   -  person user2864740    schedule 20.10.2013
comment
Тем, кто голосовал за закрытие: предыдущий вопрос касается только части init / alloc. Как видите, у меня также возникла странная проблема с компилятором. Думаю, здесь есть два отдельных вопроса, на один из которых действительно уже был дан ответ.   -  person Alex I    schedule 20.10.2013
comment
Ivars в категориях - это функция только для Clang, если только GCC не добавил ее в самом недавнем прошлом. Вам нужна библиотека времени выполнения для отправки сообщений, если ничего другого, независимо от того, что вы хотите делать с корневым классом. GNU libobjc является частью GNUStep; Я не знаю, можно ли их разделить, но возможно.   -  person jscs    schedule 20.10.2013
comment
@JoshCaswell: Спасибо! Отправка сообщений мне не нужна, это минимально. Насчет libobjc / GNUStep, интересно, но у меня нет заголовков, например Foundation.h   -  person Alex I    schedule 20.10.2013
comment
Вам действительно нужна отправка сообщений. Это фундаментальный механизм Objective-C [[MyObject alloc] init] содержит две отправки сообщений. Вам нужно objc_msgSend(). Возможно, ваш компилятор автоматически включает libobjc, когда вы компилируете исходный код ObjC, без вашего ведома.   -  person jscs    schedule 20.10.2013
comment
Однако, насколько я понимаю, ваша основная проблема с компилятором, похоже, заключается в том, что Аарон Голден указал ниже.   -  person jscs    schedule 20.10.2013
comment
К сожалению для вас, не так много людей пишут код ObjC для платформ, отличных от Apple. Теоретически это переносимый язык, потому что это просто слой поверх C, но сам этот слой должен быть портирован. Я бы посоветовал взглянуть на корневые классы GNUStep или Apple для получения информации. (Примечание; когда я говорил о категориях выше, я имел в виду расширения, которые также могут быть недоступны через GCC.)   -  person jscs    schedule 20.10.2013
comment
@JoshCaswell: Ага, вот чего я боялся. Теоретически это переносимый язык, но ...   -  person Alex I    schedule 20.10.2013
comment
Из любопытства, почему вы хотите использовать ObjC? Просто пробовать?   -  person jscs    schedule 20.10.2013
comment
@JoshCaswell: У меня уже есть кодовая база в ObjC. Возможно, лучше преобразовать в C, на самом деле это не так сильно привязано к материалам ObjC.   -  person Alex I    schedule 20.10.2013


Ответы (2)


Можно создавать классы без базового класса. Происходит пара вещей. Во-первых, вашему компилятору не нравится синтаксис расширения класса "()". Другим компиляторам это подойдет. Если вы удалите эти «()» в четвертой строке MyObject.m, ваш компилятор будет жаловаться на то, что у вас есть два дублирующих интерфейса для класса MyObject. Для целей вашего теста вы должны переместить эту переменную _field в объявление MyObject в файле заголовка, например:

@interface MyObject {
    int _field;
}
-(void)myMethod:(int)param;
@end

Затем вы можете полностью удалить этот лишний @interface в файле .m. По крайней мере, с этого вы должны начать.

person Aaron Golden    schedule 20.10.2013
comment
Спасибо! Без круглых скобок я получаю следующее: MyObject.m: 4: 1: предупреждение: дублирующееся объявление интерфейса для класса MyObject [включено по умолчанию] MyObject.m: 6: 1: ошибка: переопределение struct MyObject Во включенном файле из MyObject.m: 1: 0: MyObject.h: 3: 1: примечание: изначально определено здесь MyObject.m: In function '- [MyObject myMethod:]': MyObject.m: 17: 3: error: '_field' необъявленный (первое использование в этой функции) - person Alex I; 20.10.2013
comment
Попробую другие компиляторы. Не могли бы вы также сказать мне, что входит в метод init () класса без базового класса? Еще раз спасибо... - person Alex I; 20.10.2013
comment
вы имеете в виду -init? -init обычно ничего не делает, кроме инициализации ivar. в этом случае вы можете захотеть определить свой собственный init, который ничего не делает и + alloc выделяет память, используя malloc или что-то еще. Среда выполнения может потребовать некоторого согласования, так что ... ну, я думаю, вам не следует тратить время зря и просто использовать GNUstep. Просто установите фундамент, если вам не нужен графический интерфейс. Это проблема, намного превышающая ваш опыт AFAICT. - person Fred Frith-MacDonald; 21.10.2013
comment
Синтаксис расширения класса (с iVars) поддерживается только в clang, GCC никогда его не реализовал. - person Richard J. Ross III; 26.10.2013

Это возможно, но обратите внимание, что NSObject реализует API распределения памяти в objective-c, и если вы не реализуете NSObject +alloc и -dealloc или эквивалентные в корневом классе, вам все равно придется реализовать ту же функциональность для каждого класса.

person James    schedule 25.10.2013