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
精彩评论