0

In Java I have a class like this:

public interface Test {

public final static String TAG = "Tag";

}

And other classes are able to implement this Interface and use the declared variables in my interface!

Now I want to do the same thing in Objective C and i found Protocols and tried it like this:

@protocol Test <NSObject>

NSString *const TAG = @"Tag";

@end

But that didn't work! What's the correct way?!

UPDATE:

That Question here is exactly what i am looking for:

how to do it on objective-c: extending protocol and interface like in java

But there´s no proper answer!

Community
  • 1
  • 1
davidOhara
  • 1,008
  • 5
  • 17
  • 39
  • Not really a good way to do this (the Java way isn't even particularly good). Use C constants where you can, statics (ie, `extern`) is you must, `#define` if you're really desperate. And, as noted, this has no real connection to protocols. – Hot Licks Jan 10 '14 at 01:26

4 Answers4

1

Asking before researching is a terrible habit.

In Java public final static String TAG = "Tag"; is just as making a global constant in Objective-C. Just declare that out side the protocol.

static const NSString *TAG = @"Tag";

@protocol Test <NSObject>

-(...)...

@end
TwilightSun
  • 2,275
  • 2
  • 18
  • 27
  • When putting the definition in the header, each compilation unit that includes the header will create it's own symbol. The linker will catch the duplicated symbols. You have to specify `extern`. – Nikolai Ruhe Jan 09 '14 at 15:26
  • Use `extern NSString * const TAG;` in `.h` file and then define the string in a `.m` file. Otherwise you'll get linker errors complaining about duplicate symbols. – DarkDust Jan 09 '14 at 15:38
  • @DarkDust no you don't have to do it that way if its just a constant, write **static** const NSString* TAG = @"TAG"; will eliminate the error. – TwilightSun Jan 10 '14 at 01:14
  • @TwilightSun: You can "solve" this with `static` instead, but this has the disadvantage that every compilation unit that includes this `.h` (read: every `.m` file that includes this `.h`) will get its own version of `TAG`. Include this in 100 `.m` files, you get 100 copies of `TAG`. – DarkDust Jan 10 '14 at 07:45
  • @DarkDust static const is processed at compile time not in runtime. Just as inline blocks, the compiler will integrate the code into were it's used instead of allocating a stack memory for it. You won't get link issue nor memory issue. So in short you won't get 100 copies, you won't even have one copy because the compiler will just treat it as a literal. Actually **this is** how you should do to define a **global constant** in a header file if you don't want to use the ugly #define macros. – TwilightSun Jan 10 '14 at 07:51
  • @TwilightSun That is exactly what i want! Finally someone who understands what i really was looking for...:) Thx for that! – davidOhara Jan 10 '14 at 08:17
1

Like this:

@protocol Test <NSObject>

@property (readonly) NSString *TAG;

@end

and within the class that implements this protocol, you will need to provide:

- (NSString *)TAG {
    return @"Tag";
}
trojanfoe
  • 120,358
  • 21
  • 212
  • 242
  • Wouldn't it be better to create a base class with this implementation instead of protocol for such usage ? Maybe add suggestion for that - otherwise it sounds like a lot of copy pastes and modifying @"Tag" to something else will be painful and potentially dangerous - really unsecure solution. – Grzegorz Krukowski Jan 09 '14 at 15:14
  • Thats not what i want! I want to have a class with fixed Var´s...I just want to use these vars in other classes...But not setting them in other classes... – davidOhara Jan 09 '14 at 15:18
  • 1
    @chrizstone then why ask explicitly how to define a variable within a `@protocol` when all you want is some global variable? Your question is misleading and you appear to have little understanding of the subject. Voting to close. – trojanfoe Jan 09 '14 at 15:51
  • Cause my research with google resulted in using protocols! I read that the equivalent of a java interface is a protocol... – davidOhara Jan 09 '14 at 16:08
  • @chrizstone Well using `interface`s in Java to declare global variables isn't the best approach either, so you were always on the wrong path. But then I don't suppose you understand Java either. – trojanfoe Jan 09 '14 at 16:19
  • @chrizstone Because a class must implement the `interface`, which is akin to my answer given here, which as you state yourself is "not what you want". – trojanfoe Jan 09 '14 at 16:23
  • Sure a class must implement an interface! That´s what i want like i wrote in my Question...I just want to know whats the equivalent in objc – davidOhara Jan 09 '14 at 16:29
  • @chrizstone My answer is the closest you'll get, but the actual value is within the implementation file, not the header file. – trojanfoe Jan 09 '14 at 16:30
  • So than i have to provide my var´s in every class that implements my interface?! – davidOhara Jan 09 '14 at 16:35
  • @chrizstone Yes, unless you derive those classes from a common base class, as suggested by the first comment on this answer. – trojanfoe Jan 09 '14 at 16:42
1

In the header file declare a global variable:

extern NSString * const kTAG;

In one implementation file define and initialize the variable:

NSString * const kTAG = @"Tag";
Nikolai Ruhe
  • 81,520
  • 17
  • 180
  • 200
  • so without using a @protocol?! – davidOhara Jan 09 '14 at 15:22
  • @chrizstone global variables and `@protocols` are orthogonal concepts. Objective-C does not know class/protocol variables. You're free to declare the variable in the protocol's header file. – Nikolai Ruhe Jan 09 '14 at 15:24
  • so how can i implement it in objc, the way i do it in java?! – davidOhara Jan 09 '14 at 15:27
  • @chrizstone You can't. Above solution is the way to go. – Nikolai Ruhe Jan 09 '14 at 15:30
  • So i don't need protocols! I Just make a new class with .h and .m and declare my Var´s! And then in my other class in .h i will do "@interface Testclass : Test"? – davidOhara Jan 09 '14 at 15:33
  • @chrizstone I'm not sure what you mean, but yes: just use the variable wherever you want. It's not tied to the protocol in any way. – Nikolai Ruhe Jan 09 '14 at 15:46
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/44897/discussion-between-chrizstone-and-nikolai-ruhe) – davidOhara Jan 09 '14 at 15:49
  • 1
    Don't need to do it that way, if it's a global **variable**, use extern, if it's a global constant use static (no need to initialize in a separate implementation file). – TwilightSun Jan 10 '14 at 01:20
0

If you want to just have NSString as property in protocol use that:

@protocol Test <NSObject>
@property (nonatomic, retain) NSString* TAG;
@end

If you want to use constant - which is not really a variable :) just put it outside protocol block:

 static NSString* const *const TAG = @"Tag";
Grzegorz Krukowski
  • 18,081
  • 5
  • 50
  • 71