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!
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
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";
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";
}
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";
Related
I have declared private variables in implementation file of cycles.
myclass.m
#interface myclass()
#property (nonatomic) unsigned int number;
#end
Well, when I put in main.m something like this:
myclass * some = [[myclass alloc] init];
[some setNumber:10]; // no visible #interface for 'myclass' declares the selector 'setNumber'.
unsigned int a=[some getNumber]; //no visible #interface ...
Every answer on StackOverflow.com points the same as I do. What is the problem?
You can use readonly/readwrite property definitions to achieve this.
In MyClass.h
#interface MyClass : NSObject
#property (nonatomic, readonly) NSNumber *number;
#end
In MyClass.m
#interface MyClass ()
#property (nonatomic, readwrite) NSNumber *number;
#end
You can now read the number property outside of the class, and you will only be able to change it inside of MyClass.m. You can set it's value like so, self.number = 5 inside of MyClass.m.
Objective-C does not have the same type of private variables that a language like Java has. What is it that you are trying to accomplish with a private variable?
The problem is that the property number is a private property because you declared it in the interface section in your .m file. Declare it in your header myclass.h files interface block instead.. A private property, ivar, or method is one which can only be accessed from within an instance of your myClass object by using the self keyword (which is basically a pointer to the myClass instance within which you are currently executing).
Moving your property declaration to the header file will make the property accessible from outside the class instance. In other words, it makes it public.
If you want to restrict access to the data the property points to, define the property in the header file as a readonly property:
MyClass.h
#interface MyClass : NSObject
#property (nonatomic, readonly) unsigned int number;
#end
Then in your .m file create a private ivar manually and override the getter for the number property as follows:
MyClass.m
#implementation MyClass {
//Instance variable (ivar)
unsigned int _number;
}
unsigned int number()
{
return _number;
}
#end
That way a subclass (or anyone else for that matter) can't muck with the value of number. You can then access number in your main function as follows:
MyClass* myClass = [[MyClass alloc] init];
unsigned int newNumber = myClass.number; //There is no such selector called getNumber BTW, only number.
Here's my question.
Let's say I have a class called WebServiceBase.h. And I need to add a iVar in to that class called NSString *requestData. But I don't need to add that iVar in to the header file and make it visible to the external people. (If I'm distributing this as a class library)
Also I need to be able to access this requestData iVar, within the other classes that is extended from the WebServiceBase.h. (These extended classes are written by me. Not from the external people)
I tried with declaring the requestData iVar within the class extensions. But then it's not visible to the extended classes.
Any solution for this? I need to protect my data and make it hide from the external world.
You can define your ivars as protected via the #protected keyword, meaning that your class and all subclasses can access it without any problem, but the compiler won't allow this for other classes which don't inherit from your base class:
#interface Foo : NSObject
{
#protected
NSObject *a;
}
Its as simple as that and already gives you all the safety you can get from Objective-C.
You can have an ivar definition block in the #implementation block.
there are 2 ways , you can choose one you like.
1).h file
#interface YourClass
{
}
.m file
#interface YourClass ()
#property (nonatomic, retain) NSString *title;
#end
#implementation YourClass
#synthesize title;
//your method
2) .h flie
#interface YourClass
{
}
.m file
#implementation YourClass
{
NSString *title;
}
//your method
Declare a class extension that defines the ivar in another .h file. Call it something like myclass-private.h. Then import that header in both your main class your subclasses.
There are 3 modifiers: #private, #protected (default) and #public. So if i define a instance variable as private then that should not be accessible from anywhere.
For E.g. -
#interface A {
#private
NSString *a;
}
#property(nonatomic, retain) NSString *a;
Now inside implementation of some other interface/class B-
-(void)getSomeValue {
A *object = [[A alloc] init];
NSString *value = object.a;
.........
}
Here i am able to access instance variable, although i defined that as private.
It is a bit confusing, although when i look into details of this statement, then it is clear that it is calling the getter of a, but then also it seems confusing and it is against the concept of OOPS.
Anyone having any thought on this?
It's not the instance variable you're accessing but the property you declared. Don't declare the property if you do not want the instance variable to be visible outside the class.
#import <Foundation/Foundation.h>
#interface Visibility : NSObject {
#public
BOOL boolPublic;
#protected
BOOL boolProtected;
#private
BOOL boolPrivate;
}
#property (nonatomic, assign) BOOL boolPublic;
#property (nonatomic, assign) BOOL boolProtected;
#property (nonatomic, assign) BOOL boolPrivate;
#end
#implementation Visibility
#synthesize boolPublic;
#synthesize boolProtected;
#synthesize boolPrivate;
#end
int main(int argc, char *argv[]) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
Visibility *visibility = [[Visibility alloc] init];
visibility.boolPublic = YES;
visibility.boolProtected = YES;
visibility.boolPrivate = YES;
// Place following NSLog()'s here
[pool release];
}
Let's try this out
Using the methods you define with #property/#synthesize
NSLog(#"Accessors %d %d %d", visibility.boolPublic, visibility.boolProtected, visibility.boolPrivate);
=> 2012-01-08 17:46:40.226 Untitled[2592:707] Accessors 1 1 1
Accessing #public ivar directly
NSLog(#"Public %d", visibility->boolPublic);
=> 2012-01-08 17:46:40.228 Untitled[2592:707] Public 1
Accessing #protected ivar directly
NSLog(#"Protected %d", visibility->boolProtected);
=> error: instance variable 'boolProtected' is protected
=> NSLog(#"Protected %d", visibility->boolProtected);
=> ^
Accessing #private ivar directly
NSLog(#"Private %d", visibility->boolPrivate);
=> error: instance variable 'boolPrivate' is private
=> NSLog(#"Private %d", visibility->boolPrivate);
=> ^
When you are accessing using dot notation this:
visibility.boolPublic
is equivalent to:
[visibility boolPublic]; // <- This is a method call
Because you set it as a #property and you claim it in header file. The variable you set as a #property will auto generate getter and setter for this variable and they are both public method to get or set it(variable is still private). If you really want to make the property as an private method, you should claim it in .m file and it will become private. You can only use this variable in the .m file.
For example, in your .h file
#interface ClassWithPrivateProperty : NSObject {
#private
NSString* member;
}
- (void) trySettingPrivateProperty;
#end
in your .m file
#import "ClassWithPrivateProperty.h"
#interface ClassWithPrivateProperty ()
#property (nonatomic,retain) NSString* member;
#end
#implementation ClassWithPrivateProperty
#synthesize member;
- (void) trySettingPrivateProperty {
self.member = #"A Value";
NSLog(#"myClass.member = %#", self.member);
}
#end
You can check more detail in Private properties for iPhone Objective-C
Edit:
Thanks for Abizern and Paul's comment, but in fact I got nothing compile error for this program.
I think RIP's question is "Why I set the variable in #private but I can still modify the variable like instance.variable"
The answer is although he set the variable as #private, but claim #property for variable in .h file also provide public methods getter and setter. So he can still get the instance variable use instance.variable. For OOP design pattern you should not expose your internals publicly. So if you want to use a variable privately only in its class and no one know it. And you still want to use getter and setter to access this variable in its class. you should claim #property in .m file like I did above. I claim the #property in .m file, it's a #interface extension(unnamed category). So you can make it "like" private. Because you cannot access this variable from anywhere outside this class. So it's just like a "private #property" that I mention about.
Two useful articles for you Public Properties with Private Setters and Private properties for iPhone Objective-C
for private methods,
I could use
#interface MyClass(PrivateMethods)
- (void) _foo;
#end
How do you declare a private member variable in objective c?
http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocDefiningClasses.html#//apple_ref/doc/uid/TP30001163-CH12-TPXREF127
#interface MyClass : Superclass {
#private
NSString * privateString;
}
#end
You can declare it as follows..
#private //variable;
Check this question out.
Question- private-instance-variable
Hi i will try to explain my problem: i'm working with webservices and i need to give variable or label.text to webservice request wich is in another class... I tried in lots ways, but i can't find solution. I know it must be very easy, but i'm new in objective-c so i have problem in primitive situation. Thanks for everyone who will help me :)
Use an instance variable and a property. See here.
In .h:
#interface YourClass : Superclass {
NSString *text;
}
#property (nonatomic, retain) NSString *text;
in .m you have to synthesize it:
#implementation YourClass
#synthesize text;
now you can set this variable like so:
[instanceOfYourClass setText:someText];
get it like so:
someString = [instanceOfYourClass text];
and use it like so (in your implementation):
someString = [self text];