3

我正在尝试在 Windows 上学习目标 c。我的程序编译时出现警告

我的代码是

#include <objc/Object.h>

@interface Greeter:Object
{
  /* This is left empty on purpose:
   ** Normally instance variables would be declared here,
   ** but these are not used in our example.
   */
}

- (void)greet;

@end

#include <stdio.h>

@implementation Greeter

- (void)greet
{
    printf("Hello, World!\n");
}

@end

#include <stdlib.h>

int main(void)
{
    id myGreeter;
    myGreeter=[[Greeter alloc] init];
    [myGreeter greet];
    [myGreeter release];
    return EXIT_SUCCESS;
}

我使用以下命令在 GNUStep 上编译我的程序

 gcc -o Greeter Greeter.m -I /GNUstep/System/Library/Headers -L /GNUstep/System/Libra
 /Libraries -lobjc -lgnustep-base -fconstant-string-class=NSConstantString

我在编译时收到以下警告

: 'Greeter' may not respond to '+alloc' [enabled by default]
: (Messages without a matching method signature [enabled by default]
: will be assumed to return 'id' and accept [enabled by default]
: '...' as arguments.) [enabled by default]
: no '-init' method found [enabled by default]
: no '-release' method found [enabled by default]

因此,当我运行我的可执行文件时,该对象不会被实例化。

我正在使用来自 MinGW 的 gcc,其中 gcc 版本是 4.6.2

- 更新 - -

当我从 NSObject 而不是 Object 扩展时,程序运行良好

--更新 2 ----

我的 Object.h 看起来像

#include <objc/runtime.h>

@interface Object
{
    Class isa;
}
@end

--更新 3 ----

我修改了我的代码如下。它编译得很好,但我不确定这是否是正确的处理方式

@interface Greeter
{
  /* This is left empty on purpose:
   ** Normally instance variables would be declared here,
   ** but these are not used in our example.
   */
}

- (void)greet;

+ (id)alloc;
- (id)init;
- release;

@end

#include <stdio.h>

@implementation Greeter

- (void)greet
{
    printf("Hello, World!\n");
}

+ (id)alloc
  {
    printf("Object created");
    return self;
  }

- (id)init
  {
    printf("Object instantiated");
    return self;
  }

- release {}

@end

#include <stdlib.h>

int main(void)
{
    id myGreeter;
    myGreeter=[[Greeter alloc] init];
    [myGreeter greet];
    [myGreeter release];
    return EXIT_SUCCESS;
}
4

5 回答 5

18

除非你正在研究 Objective-C 的历史,否则试图学习基于 Object 类的语言完全是浪费时间。该类Object最后一次普遍用作根类是在 1994 年之前的 NEXTSTEP。

如果您的目标学习 1994 年之前的 Objective-C,那么请说明,因为如果是这样,那么到目前为止您的答案是完全错误的。即使目标是采用现代模式,答案也更How do I recreate NSObject?接近于其他任何东西。请注意,如果是您的目标......好吧......去吧!1994 年之前的 Objective-C 有点像 OOP 宏程序集,通过这种方式,在金属简单性方面有大量的力量。

例如,您说“我已按如下方式修改了我的代码。它编译得很好,但我不确定这是否是正确的处理方式”。

该代码可以编译,但是——不—​​—它不起作用。一点也不。对于初学者来说,该+alloc方法实际上并没有分配任何东西。该类也没有Greeter实现足够多的功能来执行类似NSObject.

如果您的目标是学习类似于现代 Objective-C 的东西并使用 Windows 来完成,那么最好的方法可能是安装 GNUStep 工具链。这样,至少,您将针对NSObject类似于现代 Cocoa(以及在较小程度上,iOS)的一组有根 API 进行编程。

如果您的目标是学习真正现代的 Objective-C,那么您至少需要一个可以运行最新版本 LLVM 的环境。当然,如果你想编写基于 Objective-C 的 iOS 或 Mac OS X 应用程序,你会想要一台运行 Lion 的 Mac。

于 2012-04-14T17:12:45.917 回答
3

从内存中,Object该类没有实现保留计数,所以它不会有release,它会有free或其他一些方法。它应该有+alloc-init虽然。由于没有“Objective-C 标准”,你必须打开你的objc/Object.h,看看它到底提供了什么。

请注意,在 GCC 4.6.2 上,objc/Object.h实际上包括objc/deprecated/Object.h,这意味着对Object作为类的支持可能相当有限。如果它不包含它,请尝试自己包含它:

#import <objc/deprecated/Object.h>
于 2012-04-12T09:14:56.353 回答
2

进口基金会。

#import <Foundation/Foundation.h>

扩展 NSObject 而不是 Object。

@interface Greeter : NSObject
于 2012-04-12T09:26:11.660 回答
0

您是否尝试过 [Greeter new];? 打开 Object.h 并查看 Object 类中定义的方法...

编辑:要实现分配、保留和释放,您必须调用 objc 运行时。所以..我认为你必须写这样的东西:

@interface RootObject : Object
+ (id)alloc;
- (id)init;
- (id)retain;
- (void)release;
@end


@implementation RootObject
{
    unsigned int retainCount;
}

+ (id)alloc
{
    id myObj = class_createInstance([self class], 0);
    return myObj;
}
- (id)init
{
    retainCount = 1;
    return self;
}
- (id)retain
{
    retainCount++;
    return self;
}
- (void)release
{
    retainCount--;
    if (retainCount == 0) {
        object_dispose(self);
    }
}

@end

然后你可以继承 RootObject。

于 2012-04-12T09:08:07.817 回答
0

我所做的是将 gcc-4.6 与 linux 系统附带的 4.7 一起安装。它似乎有效,因为它具有旧代码的兼容性层。在我的基本 Makefile 中,我指定

>     CC=gcc-4.6
>     LIBS=-lobjc -lpthread
>     
>     all:       objc-test.m
>         $(CC)  -o objctest  objc-test.m $(LIBS)

使用旧版本的 gcc 并没有什么“错误”。新的 4.7 版本已经破坏了 objc 系统,因此它不是一个独立的编译套件。太糟糕了。我想有一些原因,可能是政治原因,可能只是很难让一个编译器为每个人都做这一切。在以旧方式失败两天后,我已经成功地在 X86_64 Linux 中使用 gcc 4.7.3 使用 gnustep 制作了 objc 程序。

它涉及一堆设置:

设置环境变量

源 /usr/share/GNUstep/Makefiles/GNUstep.sh

并符合他们的构建系统。
一个基本的GNUmakefile

include $(GNUSTEP_MAKEFILES)/common.make

TOOL_NAME = test

test_OBJC_FILES = main.m  

include $(GNUSTEP_MAKEFILES)/tool.make

为了

主.m:

#import <Foundation/Foundation.h>

int
main (void)
{ 
  NSLog (@"Executing");
  return 0;
}

跑步

gs_make

在 subdir 中构建二进制文件 obj

与这样的构建系统抗争实际上非常令人沮丧,并且不得不花费数小时从文档中梳理出花絮,才能从如此出色的编译器中获得基本功能。我希望他们在未来的迭代中修复它。

于 2013-10-28T04:09:21.197 回答