1

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 don't know how to implement that static { } part in Java.

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 Address : 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 global. 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 global variable. So my question is how to make "localIpAddress" variable as a global variable which is initialized once when the first time Address class is created..

Cœur
  • 37,241
  • 25
  • 195
  • 267
codereviewanskquestions
  • 13,460
  • 29
  • 98
  • 167
  • possible duplicate of [Static constructor equivalent in Objective-C?](http://stackoverflow.com/questions/992070/static-constructor-equivalent-in-objective-c) – Will Hartung Feb 17 '11 at 05:58

4 Answers4

1

Look here to emulate Java's static block in Objective C: Static constructor equivalent in Objective-C?

Community
  • 1
  • 1
blizpasta
  • 2,624
  • 3
  • 25
  • 31
1

You can implement this as a class method, storing the IP address in a static variable.

Address.h

@interface Address : NSObject
+ (NSString *)localIPAddress;
@end

Address.m

#import "Address.h"

static NSString *localIPAddress = nil;

@implementation Address

+ (NSString *)localIPAddress {
  if (!localIPAddress) {
    localIPAddress = @"127.0.0.1";
  }

  return localIPAddress;
}

@end
Jonathan Sterling
  • 18,320
  • 12
  • 67
  • 79
yan
  • 20,644
  • 3
  • 38
  • 48
  • Thanks for you answer. But the point is how to call getLocalIpAddress() method when the first instance of Address class is created. This is a class method so I know that I can call this method without initializing the Address class. But what I am trying to do is that call getLocalIpAddress() method and assign the value which is being returned from the method to the static variable when the first instance of Address class is created.. – codereviewanskquestions Feb 17 '11 at 06:38
1

The linker error occurs because you have an extern declaration but no definition. To fix the particular error, you need to put in your .m file something like:

NSString *localIpAddress = @"some value";

What extern does is tell the compiler that, by the time link time comes around, there will be a variable called localIpAddress, even though there isn't now. The line above in the .m file creates some space in the data segment for the NSString* and then initialises it to point at a constant string.

A better pattern for Objective-C programs is to expose the variable via a class method e.g.

static localIpAddress; // static limits visibility to this file.

-(void) initialize
{
  if (self == [Address class]) 
  {
    localIPAddress = /* whatever */;
  }
}

+(NSString*) localIpAddress
{
    return localIpAddress;
}

Or I prefer

+(NSString*) localIpAddress
{
    static NSString* localIpAddress = nil;
    if (localIpAddress == nil)
    {
        localIpAddress = /* Do whatever you need to get it */ ;
    }
    return localIpAddress;
}
JeremyP
  • 84,577
  • 15
  • 123
  • 161
0

It sounds like you only want localIPAddress to be created the first time an instance is created, but not via a class method. This is a rather odd scenario, but nonetheless try this:

static NSString *localIPAddress = nil;

@implementation Address

- (id)init {
    if ((self = [super init])) {
        if (!localIPAddress) {
            localIPAddress = //getAddress
        }
    }
    return self;
}

@end

Of course this is a very unusual setup. You would generally either get the local ip address each time you create the object, or you would use Jonathan's code to get it via a class method.

Martin Pilkington
  • 3,261
  • 22
  • 16