2012-04-12 29 views
2

我正試圖在Windows上學習目標c。我的程序有警告使用gcc進行目標C編譯4.6.2

編譯

我的代碼是

#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; 
} 

我使用下面的命令

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

彙編GNUstep的我的計劃,我得到的編譯

: '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 MinGW的,從哪裏gcc版本4.6.2是

--update ---

程序運行正常,當我從延長NSObject的,而不是對象

--update 2 ----

我Object.h看起來像

#include <objc/runtime.h> 

@interface Object 
{ 
    Class isa; 
} 
@end 

--UP日期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; 
} 
+0

該代碼編譯正常;但它什麼也沒有做。它不會分配歡迎詞,永遠不會調用init,也不會釋放任何東西。基於Object類的學習Objective-C在1994年以前會很有用。現在?幾乎所有的Objective-C在任何地方都使用NSObject作爲根類,並且幾乎定義了剩餘語言的細節(包括近來的一些語法)。 – bbum 2012-04-14 17:06:40

回答

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> 
+0

我已經更新了我的問題,看看我的Object.h如何看起來像 – 2012-04-12 09:16:48

+0

@Anand:我更新了我的答案 – dreamlax 2012-04-12 09:19:32

+0

是不可能在沒有擴展Object或NSObject的情況下實例化對象? – 2012-04-12 09:33:46

0

你試過[Greeter新]; ?打開Object.h並查看Object類中定義的方法...

編輯: 要實現alloc,保留和釋放,必須調用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。

+0

是的,我已經嘗試過新的,它不工作 – 2012-04-12 09:14:50

+0

看到Object.h它很明顯,它不能工作。 Object中沒有方法。要麼自己創建它們,要麼使用NSObject – Francesco 2012-04-12 09:23:35

+0

我編輯了我的答案。 – Francesco 2012-04-12 13:46:52

2

導入基金會。

#import <Foundation/Foundation.h> 

擴展NSObject而不是Object。

@interface Greeter : NSObject 
+0

這是更好的方法,因爲對oldschool Object類的支持迅速下降。 – dreamlax 2012-04-12 09:28:00

+0

需要注意的是,在Windows上,這需要GNUStep,一個WebObjects開發工具的副本,或者 - 可能,儘管它現在可能是一個死亡項目 - Cocotron。 – bbum 2012-04-14 17:16:22

18

除非您正在研究Objective-C的歷史,否則嘗試根據Object類學習語言是完全浪費時間。 Object類最後一次在1994年以前的NEXTSTEP中用作根類。

如果您的目標要學習1994年以前的Objective-C,那麼說明因爲,如果是的話,那麼迄今爲止的答案完全是錯誤的。即使目標是與現代模式,答案更符合How do I recreate NSObject?比其他任何線。請注意,如果是你的目標....好吧...去吧! 1994年以前的Objective-C有點像面向對象宏觀組裝,通過這種方式,通過簡單的金屬實現了大量的權力。

例如,你說「我修改了我的代碼,如下所示:編譯好,但我不確定這是否是正確的方法。

該代碼編譯,但 - 沒有 - 它不起作用。一點也不。對於初學者,+alloc方法實際上並沒有分配任何東西。 Greeter類也沒有實現足夠的功能來執行類似NSObject的任何操作。

如果你的目標是學習類似於現代Objective-C的東西,並使用Windows來完成,最好的方法可能是安裝GNUStep工具鏈。因此,至少,您將針對類似於現代可可(以及在較小程度上,iOS)的一組根源化的API進行編程。

如果你的目標是要學習真正的現代Objective-C,你至少需要一個能夠運行最新版本的LLVM的環境。當然,如果您想編寫基於Objective-C的iOS或Mac OS X應用程序,則需要運行Lion的Mac。

+0

+1,但GNUstep是(或者)是一個可怕的黑客攻擊......我試圖通過源代碼,它充滿了諸如「這是一個黑客」和「FIXME:令人難以置信的糟糕的黑客」等評論。源頭上的「黑客」揭示了一個驚人的數字。我一直在GNUstep和GCC的libobjc之間翻轉,這也沒有更好的(或者至少,它不是我正在看的版本)。我真的希望現在比我幾年前看到的好多了。我正在考慮提供代碼,但誠實地說......我幾乎找不到所有黑客的方法。 – dreamlax 2012-04-15 04:18:14

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成功完成objc程序後,gnustep在舊的兩天內失敗了兩天。

它涉及到一堆設置的:

建立與

源/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 

的main.m:

#import <Foundation/Foundation.h> 

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

運行

gs_make

在子目錄obj中構建二進制文件。

它實際上是相當令人沮喪與構建系統一樣, 打,不得不花費大量時間梳理出tidbitsfrom文檔只是從這樣一個偉大的編譯器得到基本功能 。我希望他們在即將到來的迭代中修復它。