2

刚从 Java 背景学习 Objective-C。我正在尝试编写一个除了教我如何用这种语言编写函数之外没有其他目的的程序,而且我到处都遇到错误。问题是因为我昨天刚开始使用这种语言,所以这些错误对我来说毫无意义。这是我到目前为止所拥有的。

主要方法:

int main (int argc, const char * argv[])
{
    @autoreleasepool
    {
        NSString * prompt = @"Hello World";

        prompt = writePromptMessage(prompt);

        NSLog(@"%@", prompt);
    }

    return 0;
}

特殊方法:

NSString *writePromptMessage(NSString * prompt)
{
    return prompt;
}

我的错误:

  • 函数 writePromptMessage 的隐式声明在 C99 中无效
  • ARC 不允许将“int”隐式转换为“NSString *”
  • 从 int 分配 NSString strong 的不完整整数到指针转换
  • writePromptMessage 的冲突类型
4

3 回答 3

4

与 Java 不同,您需要在使用它之前添加一个函数声明(也称为函数原型)。函数声明就像函数定义一样,但没有函数体(即代码),并以分号结尾:

// This is a function declaration:
NSString *writePromptMessage(NSString * prompt);

// This is a function definition:
NSString *writePromptMessage(NSString * prompt)
{
    // Function body goes here
}

为了能够调用一个函数,你需要在使用站点之前写一个声明:

NSString *writePromptMessage(NSString * prompt);  // declaration

int main (int argc, const char * argv[])
{
    ...
    writePromptMessage(...);  // usage
}

// definition follows

或者,您可以将整个定义放在使用站点之前,但这并不总是可行的(例如,如果您有两个可以相互调用的函数)。

C 和 Objective-C 实际上允许你调用没有可见声明的函数,但这被认为是一个弃用的特性,因为它很容易被误用并导致细微的错误:

如果在没有可见声明的情况下调用函数,编译器会创建一个隐式声明

  • 隐式声明采用任意数量和类型的参数
  • 隐式声明返回int

因此,发生的事情是编译器假设它在第一次看到它时writePromptMessage返回int,这是错误的,并且会导致一连串其他错误。对于不返回的函数int,你不能使用隐式函数声明,而对于确实返回的函数int,你不应该使用隐式函数声明。

于 2012-11-14T16:43:35.853 回答
2

您要么需要在 之前添加函数声明main,要么在那里定义整个函数。例如,它编译:

#import <Foundation/Foundation.h>

void hello(NSString *text) {
    NSLog(@"%@", text);
}

int main(int argc, const char * argv[])
{
   @autoreleasepool {
        hello(@"Foo");
    }
    return 0;
}

这也是如此:

#import <Foundation/Foundation.h>

void hello(NSString*);

int main(int argc, const char * argv[])
{
   @autoreleasepool {
        hello(@"Foo");
    }
    return 0;
}

void hello(NSString *text) {
    NSLog(@"%@", text);
}

编译器会自动注意到 Objective-C方法那是另一回事),因此无需提前声明它们;这编译得很好:

@interface Foo : NSObject
@end

@implementation Foo

- (void) doA
{
    [self doB];
}

- (void) doB
{}

@end

显然编译器对常规 C 函数并不那么聪明,可能是为了符合 C 语言规范。

于 2012-11-14T16:45:18.757 回答
1

所有这些错误很可能源于同一个问题。看来您尚未在方法之前声明或writePromptMessage 定义main。在 C(和 Objective-C)中,您必须在使用函数之前声明或定义函数。编译器一无所知writePromptMessage,导致您的错误消息。

函数 writePromptMessage 的隐式声明在 C99 中无效

表示你还没有声明writePromptMessage,所以...

ARC 不允许将“int”隐式转换为“NSString *”

在 C 中,假定函数默认返回一个int;由于您尚未声明writePromptMessage,编译器假定它是一个返回 a 的函数,int不应将其转换为 a NSString *

从 int 分配 NSString strong 的不完整整数到指针转换

见上文(基本上是同一个问题)。

writePromptMessage 的冲突类型

哦!现在编译器已经看到了writePromptMessage……但是等等。它已经假定writePromptMessage返回一个int,现在它看到它返回NSString,导致错误。


如果你把writePromptMessage before main的定义,或者至少声明它的原型,à la:

NSString *writePromptMessage(NSString * prompt);

之前 main,你应该没事。

于 2012-11-14T16:46:32.890 回答