目标C,将错误与extern变量链接

时间:2011-02-17 07:13:28

标签: objective-c

我有一个非常简单的java代码。我不知道如何在Objective C中执行此操作。特别是,静态部分调用getLocalAddress()方法并将其分配给静态字符串变量。我知道如何在Objective中设置静态变量和静态方法,但我不知道如何在java中实现static {}部分。 提前谢谢......

public class Address {

     public static String localIpAddress;

    static {
        localIpAddress =  getLocalIpAddress();
    }

    public Address() {

    }

    static String getLocalIpAddress() {
         //do something to get local ip address
     }

}

我在.h文件中添加了这个

 #import <Foundation/Foundation.h>

 extern NSString *localIpAddress;

 @class WifiAddrss;

 @interface Address : NSObject {

 }

 @end

我的.m文件看起来像

 #import "Address.h"
 #import "WifiAddress.h"

 @implementation Address

 +(void)initialize{
     if(self == [Address class]){
         localIpAddress = [self getLocalIpAddress];
     }
 }

 +(NSString *)getLocalIpAddress{
      return address here
 }

 -(id)init{    
     self = [super init];
     if (self == nil){
         NSLog(@"init error");
     }

     return self;
 }
 @end

现在我收到一个链接错误,它抱怨“extern NSString * localIpAddress”部分。如果我将extern更改为static,它可以正常工作。但我想做的是我想把“localIpAddress”变量的范围变成grobal。因为如果我将“静态”放在Objective-C中的变量前面,那么变量只在类中可见。但是这一次,我想把它作为一个grobal变量。所以我的问题是如何将“localIpAddress”变量作为一个grobal变量,在第一次创建Address类时初始化一次。提前感谢...

3 个答案:

答案 0 :(得分:3)

您已在.h文件中声明了该变量(告诉编译器它是否存在以及它是哪种类型),现在您需要在.m文件中定义它(实际上使其存在)。

只需将NSString *localIpAddress;添加到.m文件中,或者更好:

NSString *localIpAddress = nil;

(也就是说,给它一个合理的默认值)

extern关键字表示:存在给定名称和类型的变量,但实际上存在于需要链接的“外部”文件中。因此,对于每个extern声明,您需要在一个实现文件中实际定义变量(.c,.cxx / .c ++ /。cpp,.m;此机制是C标准的一部分,目标是-C是站着的。

答案 1 :(得分:1)

除非您希望其他模块直接访问localIpAddress而不使用您的类,否则请在您的实现(.m)文件中将其声明为static

extern应在以下场景中使用:

  • 模块将变量定义为全局变量。该特定翻译单元不得使用extern
  • 其他模块需要直接访问该变量。那些特定的翻译单元必须使用extern

由于情况并非如此,请在您的实现(.m)文件中执行以下操作:

static NSString *localIpAddress;

// …

+(NSString *)getLocalIpAddress{
    return localIpAddress;
}

并删除

extern NSString *localIpAddress;
来自标题(.h)文件的

每当您需要获取该地址时,请使用

NSString *addr = [Address getLocalIpAddress];

顺便说一句,惯例是getter方法不以get开头。例如,您可以将该方法命名为localIpAddress

答案 2 :(得分:0)

快速解决方法是将localIpAddress变量移动到您的实现文件中。然后你不需要使用extern关键字。真的,如果你考虑一下,你有一个静态访问器,所以没有理由在头文件中有变量声明。

让我澄清一下:

接口:

#import <Foundation/Foundation.h>

@interface Address : NSObject {

}

+(void) initializeLocalIpAddress;

+(NSString *) localIpAddress;

@end

实现:

#import "Address.h"
#import "WifiAddress.h"

NSString *localIpAddress;

@implementation Address

+(void) initializeLocalIpAddress
{
    //get the local ip address here
    localIpAddress = ...;
}

+(NSString *) localIpAddress
{
    return localIpAddress;
}

-(id)init {    
     if ((self = [super init])) {
         NSLog(@"init error");
     }
     return self;
 }
 @end