Използване на 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)

РЕДАКТИРАНЕ Моят компилатор е gcc на cygwin, също има пакет gcc-objc на cygwin:

gcc --version
gcc (GCC) 4.7.3

Опитах се да потърся това онлайн и в няколко урока за Objective-C, но всеки пример за клас, който открих, наследява от NSObject. Наистина ли е невъзможно да се напише Objective-C без Cocoa или някакъв вид заместител на Cocoa, който осигурява 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
Вашият основен проблем с компилатора изглежда е това, което Aaron Golden посочи по-долу, обаче, доколкото виждам.   -  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

След това можете напълно да премахнете този допълнителен @интерфейс в .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: Във функция '-[MyObject myMethod:]': MyObject.m:17:3: грешка: '_field' недеклариран (първо използване в тази функция) - person Alex I; 20.10.2013
comment
Ще пробвам с други компилатори. Бихте ли ми казали какво става в метода init() на клас без базов клас? Благодаря отново... - person Alex I; 20.10.2013
comment
имаш предвид -init? -init обикновено не прави нищо освен инициализация на ivar. в този случай може да искате да дефинирате свой собствен init, който не прави нищо, и +alloc, който разпределя памет, използвайки malloc или нещо подобно. Времето за изпълнение може да изисква известно подравняване, така че... е, мисля, че не трябва да си губите времето и просто да използвате GNUstep. Просто инсталирайте основата, ако не искате GUI. Това е проблем, далеч над вашия опит AFAICT. - person Fred Frith-MacDonald; 21.10.2013
comment
Синтаксисът на разширението на класа (с iVars) се поддържа само в clang, GCC никога не го е прилагал. - person Richard J. Ross III; 26.10.2013

Възможно е, но имайте предвид, че NSObject имплементира API за разпределение на паметта в goal-c и ако не имплементирате +alloc и -dealloc на NSObject или еквивалент на основен клас, пак ще трябва да имплементирате същата функционалност за всеки клас.

person James    schedule 25.10.2013