开发者

Objective C, Linking Error with extern variable

I have a very simple java code like this. I don't have any idea how to do this in Objective C. Especially, the static part which calls the getLocalAddress() method and assign it into the static string variable. I know how to set a static variable and a static method in Objective but I dont know how to implement that static { } part in java. Thanks in advance...

public class Address {

     public static String localIpAddress;

    static {
        localIpAddress =  getLocalIpAddress();
    }

    public Address() {

    }

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

}

I added this in my .h file

 #import <Foundation/Foundation.h>

 extern NSString *localIpAddress;

 @class WifiAddrss;

 @interface Addre开发者_StackOverflowss : NSObject {

 }

 @end

And my .m file looks like

 #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

And Now I am getting a linking error and it complains about "extern NSString *localIpAddress" part. If I change the extern to static, it works fine. But what I wanted to do is that I want make the scope of "localIpAddress" variable as grobal. Since if I put "static" in front of a variable in Objective-C then the variable is only visible in the class. But this time, I want to make that as a grobal variable. So my question is how to make "localIpAddress" variable as a grobal variable which is initialized once when the first time Address class is created.. Thanks in advance...


You have declared the variable in your .h file (told the compiler that it exists and of which type it is), now you need to define it in your .m file (actually make it exist).

Just add NSString *localIpAddress; to your .m file, or better yet:

NSString *localIpAddress = nil;

(That is, give it a sane default value)

The extern keyword means: there is a variable of the given name and type, but actually lives in an "external" file that needs to be linked. So for each extern declaration, you need to actually define the variable in one of your implementation files (.c, .cxx/.c++/.cpp, .m ; this mechanism is part of the C standard on which Objective-C is standing).


Unless you want other modules to access localIpAddress directly without using your class, declare it as static inside your implementation (.m) file.

extern should be used in the following scenario:

  • A module defines the variable as global. That particular translation unit must not use extern
  • Other modules need to access that variable directly. Those particular translation units must use extern

Since this is not your case, do the following in your implementation (.m) file:

static NSString *localIpAddress;

// …

+(NSString *)getLocalIpAddress{
    return localIpAddress;
}

and remove

extern NSString *localIpAddress;

from your header (.h) file.

Whenever you need to get that address, use

NSString *addr = [Address getLocalIpAddress];

By the way, the convention is that getter methods do not start with get. For instance, you could’ve named that method localIpAddress.


A quick fix would be to move the localIpAddress variable into your implementation file. Then you wouldn't need to use the extern keyword. Really, if you think about it, you have a static accessor, so there's no reason to have the variable declaration itself in the header.

Let me clarify:

Interface:

#import <Foundation/Foundation.h>

@interface Address : NSObject {

}

+(void) initializeLocalIpAddress;

+(NSString *) localIpAddress;

@end

Implementation:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜