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]

そのため、実行可能ファイルを実行すると、オブジェクトがインスタンス化されません。

gccバージョンが4.6.2のMinGWのgccを使用しています

- アップデート - -

オブジェクトではなく NSObject から拡張すると、プログラムは正常に動作します

--更新 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>

Object の代わりに NSObject を拡張します。

@interface Greeter : NSObject
于 2012-04-12T09:26:11.660 に答える
0

[Greeter new] を試してみましたか? ? Object.h を開き、Object クラスで定義されているメソッドを見てみましょう...

編集: alloc、retain、および release を実装するには、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 に答える