Difference between #interface definition in .h and .m file - objective-c

Normally we use
#interface interface_name : parent_class <delegates>
{
......
}
#end
method in .h file and in .m file we synthesis the properties of variables declared in .h file.
But in some code, this #interface.....#end method is kept in the .m file also. What does it mean? What is the difference between them?
Also give some words about getters and setters for the interface file that is defined in .m file...

It's common to put an additional #interface that defines a category containing private methods:
Person.h:
#interface Person
{
NSString *_name;
}
#property(readwrite, copy) NSString *name;
-(NSString*)makeSmallTalkWith:(Person*)person;
#end
Person.m:
#interface Person () //Not specifying a name for the category makes compiler checks that these methods are implemented.
-(void)startThinkOfWhatToHaveForDinner;
#end
#implementation Person
#synthesize name = _name;
-(NSString*)makeSmallTalkWith:(Person*)person
{
[self startThinkOfWhatToHaveForDinner];
return #"How's your day?";
}
-(void)startThinkOfWhatToHaveForDinner
{
}
#end
The 'private category' (the proper name for a nameless category is not 'private category', it's 'class extension') .m prevents the compiler from warning that the methods are defined. However, because the #interface in the .m file is a category you can't define ivars in it.
Update 6th Aug '12: Objective-C has evolved since this answer was written:
ivars can be declared in a class extension (and always could be - the answer was incorrect)
#synthesize is not required
ivars can now be declared in braces at the top of #implementation:
that is,
#implementation {
id _ivarInImplmentation;
}
//methods
#end

The concept is that you can make your project much cleaner if you
limit the .h to the public interfaces of your class, and then put
private implementation details in this class extension.
when you declare variable methods or properties in ABC.h file , It
means these variables properties and methods can be access outside the
class
#interface Jain:NSObject
{
NSString *_name;
}
#property(readwrite, copy) NSString *name;
-(NSString*)makeSmallTalkWith:(Person*)jain;
#end
#Interface allows you to declare private ivars, properties and
methods. So anything you declare here cannot be accessed from outside
this class. In general, you want to declare all ivars, properties and
methods by default as private
Simply say when you declare variable methods or properties in ABC.m
file , It means these variables properties and methods can not be
access outside the class
#interface Jain()
{
NSString *_name;
}
#property(readwrite, copy) NSString *name;
-(NSString*)makeSmallTalkWith:(Person*)jain;
#end

you can even create other classes in .m file,
for instance other small classes which inherit from the class declared in .h file but having some slight different behaviour.
You could use this in a factory pattern

Related

How to simulate protected properties and methods in objective-c [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Protected methods in objective-c
The way to declare private properties is simple.
You declare that in extension that's declared in .m files.
Say I want to declare protected properties and access it from the class and subclass.
This is what I tried:
//
// BGGoogleMap+protected.h
//
//
#import "BGGoogleMap.h"
#interface BGGoogleMap ()
#property (strong,nonatomic) NSString * protectedHello;
#end
That one is compile. Then I added:
#import "BGGoogleMap+protected.h"
#implementation BGGoogleMap ()
-(NSString *) protectedHello
{
return _
}
#end
Problem starts. I can't implement class extension outside the original .m files it seems. Xcode will demand something inside that bracket.
If I do
#import "BGGoogleMap+protected.h"
#implementation BGGoogleMap (protected)
-(NSString *) protectedHello
{
return _
}
#end
I cannot access the ivar of _protectedHello declared in BGGoogleMap+protected.h
Of course I can use regular category rather than extension, but that means I can't have protected properties.
So what should I do?
The Objective-C Programming Language says this:
Class extensions are like anonymous categories, except that the methods they declare must be implemented in the main #implementation block for the corresponding class.
So you could just implement your class extension's methods in the class's main #implementation. That is the simplest solution.
A more complicated solution is to declare your “protected” messages and properties in a category, and declare any instance variables for that category in a class extension. Here's the category:
BGGoogleMap+protected.h
#import "BGGoogleMap.h"
#interface BGGoogleMap (protected)
#property (nonatomic) NSString * protectedHello;
#end
Since a category cannot add an instance variable to hold protectedHello, we need a class extension also:
`BGGoogleMap_protectedInstanceVariables.h'
#import "BGGoogleMap.h"
#interface BGGoogleMap () {
NSString *_protectedHello;
}
#end
We need to include the class extension in the main #implementation file so that the compiler will emit the instance variable in the .o file:
BGGoogleMap.m
#import "BGGoogleMap.h"
#import "BGGoogleMap_protectedInstanceVariables.h"
#implementation BGGoogleMap
...
And we need to include the class extension in the category #implementation file so that the category methods can access the instance variables. Since we declared the protectedHello property in a category, the compiler will not synthesize the setter and getter method. We have to write them by hand:
BGGoogleMap+protected.m
#import "BGGoogleMap+protected.h"
#implementation BGGoogleMap (protected)
- (void)setProtectedHello:(NSString *)newValue {
_protectedHello = newValue; // assuming ARC
}
- (NSString *)protectedHello {
return _protectedHello;
}
#end
Subclasses should import BGGoogleMap+protected.h to be able to use the protectedHello property. They should not import BGGoogleMap_protectedInstanceVariables.h because the instance variables should be treated as private to the base class. If you ship a static library without source code, and you want users of the library to be able to subclass BGGoogleMap, ship the BGGoogleMap.h and BGGoogleMap+protected.h headers, but don't ship the BGGoogleMap_protectedInstanceVariables.h header.
I wish I could tell you otherwise but you just can't. See this question for more information: Protected methods in Objective-C.
I am not sure, what you want to do? Something Hacking or Cracking of Data Abstraction out of OOPS concept?
Extensions are used to add properties. You have successfully added private property as in
#import "BGGoogleMap.h"
#interface BGGoogleMap ()
#property (strong,nonatomic) NSString * protectedHello;
#end
What are you doing in this ?
#import "BGGoogleMap+protected.h"
#implementation BGGoogleMap ()
-(NSString *) protectedHello
{
return _
}
#end
You have extended a class, now you are again implementing same class !!! Twice!!! And category only comes with .h file. I guess you are creating yourself a .m file, that not acceptable.
Private properties cant be accessed outside the class, it can be accessed only from the base class or subclass. That is what the error is.
I can't implement class extension outside the original .m files it seems.
Yes this is abstraction and data hiding of Objective-c !!!

Objective-C instance variables?

I'm sure my confusion here is just a result of being stuck in a "Java mindset" and not understanding how Obj-C differs in this case.
In Java, I can declare a variable in a class, like this, and each instance of that class will have it's own:
MyClass {
String myVar;
MyClass() {
// constructor
}
}
In Obj-C I tried to do the same thing by declaring a variable only in the .m file like this:
#import "MyClass.h"
#implementation MyClass
NSString *testVar;
#end
My expectation here was that this variable has a scope limited to this class. So I created a second class (identical):
#import "MySecondClass.h"
#implementation MySecondClass
NSString *testVar;
#end
What I'm seeing (and has me baffled) is that changing the variable in one class, affects the value seen in the other class. In fact, if I set a breakpoint, and then "Jump to Definition" of the variable, it takes me to th
I've created an extremely small Xcode project that demonstrates the problem here.
Change this:
#implementation MyClass
NSString *testVar;
#end
to:
#implementation MyClass {
NSString *testVar;
}
// methods go here
#end
and you'll get what you expected.
As you had it, you are actually creating a global variable. The two global variables were combined into one by the linker which is why both changed when you set one. The variable in curly braces will be a proper (and private) instance variable.
Edit: After being downvoted for no apparent reason, I thought I'd point out the "old" way of doing things, and the new way.
The old way:
SomeClass.h
#interface SomeClass : UIViewController <UITextFieldDelegate> {
UITextField *_textField;
BOOL _someBool;
}
#property (nonatomic, assign) BOOL someBool;
// a few method declarations
#end
SomeClass.m
#implementation SomeClass
#synthesize someBool = _someBool;
// the method implementations
#end
Now the new and improved way with the modern Objective-C compiler:
SomeClass.h
#interface SomeClass : UIViewController
#property (nonatomic, assign) BOOL someBool;
// a few method declarations
#end
SomeClass.m
#interface SomeClass () <UITextFieldDelegate>
#end
#implementation SomeClass {
UITextField *_textField;
}
// the method implementations
#end
The new way has several advantages. The primary advantage is that none of the implementation specific details about the class appear in the .h file. A client has no need to know what delegates the implementation needs. The client has no need to know what ivars I use. Now, if the implementation needs a new ivar or it needs to use a new protocol, the .h file doesn't change. This mean less code gets recompiled. It cleaner and much more efficient. It also makes for easier editing. When I'm editing the .m file and realize I need a new ivar, make the change in the same .m file I'm already editing. No need to swap back and forth.
Also note the implementation no longer needs an ivar or #synthesize for the property.
What you probably want (unless you're using a very old OS and compiler) is to just use property syntax. I.e.:
#interface MyClass : NSObject
// method declarations here ...
#property (copy) NSString* myVar;
// ... or here.
#end
This will do what you intended to do. This will implicitly synthesize an instance variable and a getter/setter pair for this variable. If you manually wanted to create the instance variable (you generally don't need that unless you need your code to work on very old MacOS versions), this is what the above code does under the hood to create the ivar:
#interface MyClass : NSObject
{
NSString* _myVar;
}
// method declarations here.
#end
Note the curly braces, which tell the compiler that this is not just a global variable somewhere in between the methods, but actually an instance variable that belongs to this object.
If you are creating the property only for internal use and don't want clients of your class to mess with it, you can hide this away a little bit in everything but the oldest ObjC compilers by using a class extension which "continues" the class declaration from the header, but can be placed separate from it (so usually in your implementation file). A class extension looks like a category without a name:
#interface MyClass ()
#property (copy) NSString* myVar;
#end
And you can either put your property declaration in there, or even ivar declarations (again wrapped in curly brackets). You can even declare the same property as readonly in the class interface, and then re-declare it identical, but as readwrite in the extension, so that clients only read it, but your code can change it.
Note that, if you didn't use ARC (that is, you've switched off the default of Automatic Reference Counting), you would have to set all your properties to nil in your dealloc method (unless they're set to weak or assign of course).
NB - All the above are #interface sections. Your actual code will go in separate #implementation sections. This is so you can have header files (.h) you can hand off to your class's clients that just contain the portions you intend them to use, and hide away implementation details in the implementation file (.m) where you can change them without having to worry someone might have accidentally used them and you'll break other code.
PS - Note that NSStrings and other objects that you want the immutable flavor of, but that also exist in a mutable flavor (i.e. NSMutableString) should always be copy properties, because that will turn an NSMutableString into an NSString so that nobody on the outside can change the mutable string underneath you. For all other object types, you generally use strong (or retain if not ARC). For your class's owner (e.g. its delegate) you usually use weak (or assign if not ARC).
In Java
MyClass {
String myVar;
MyClass() {
// constructor
}
}
In Objective-c
MyClass.h
#interface MyClass : NSObject{
NSString* str; // Declaration
}
#end
MyClass.m
#implementation MyClass
-(void)initializieTheString
{
//Defination
}
#end
In objective-c, you define the variable as private by doing like so
MyClass.h
#interface MyClass : NSObject{
NSString* _myTestVar; // Declaration
}
#end
and refer to it in the implementation class by doing like so
MyClass.m
#import "MyClass.h";
#implementation MyClass
-(void)initializieTheString
{
_myTestVar= #"foo"; //Initialization
}
#end

Expose a private Objective-C method or property to subclasses

According to some official talk, a class in Objective-C should only expose public methods and properties in its header:
#interface MyClass : NSObject
#property (nonatomic, strong) MyPublicObject *publicObject;
- (void)publicMethod;
#end
and private methods/properties should be kept in class extension in .m file:
#interface MyClass()
#property (nonatomic, strong) MyPrivateObject *privateObject;
- (void) privateMethod;
#end
and I don't think there is a protected type for things that are private but accessible from subclasses. I wonder, is there anyway to achieve this, apart from declaring private properties/methods publicly?
One way to solve this is to re-declare the property in your subclass's class extension, and then add an #dynamic statement so that the compiler won't create an overriding implementation of that property. So something like:
#interface SuperClass ()
#property (nonatomic, strong) id someProperty;
#end
....
#interface SubClass ()
#property (nonatomic, strong) id someProperty;
#end
#implementation SubClass
#dynamic someProperty;
#end
This obviously isn't ideal because it duplicates a privately visible declaration. But it is quite convenient and helpful in some situations so I'd say evaluate on a case-by-case basis the dangers involved in this duplication vs. exposing the property in the public interface.
An alternative - that is used by Apple in UIGestureRecognizer - is to declare the property in a separate category header file explicitly named as "private" or "protected" e.g. "SomeClass+Protected.h". That way, other programmers will know they ought not import the file. But, if you don't control the code you're inheriting from, that's not an option.
This is possible by using a class extension (not category) that you include in the implementation files of both the base class and subclasses.
A class extension is defined similar to a category, but without the category name:
#interface MyClass ()
In a class extension, you can declare properties, which will be able to synthesize the backing ivars (XCode > 4.4 automatic synthesis of the ivars also works here).
In the extension class, you can override/refine properties (change readonly to readwrite etc.), and add properties and methods that will be "visible" to the implementation files (but note that the properties and methods aren't really private and can still be called by selector).
Others have proposed using a seperate header file MyClass_protected.h for this, but this can also be done in the main header file using #ifdef like this:
Example:
BaseClass.h
#interface BaseClass : NSObject
// foo is readonly for consumers of the class
#property (nonatomic, readonly) NSString *foo;
#end
#ifdef BaseClass_protected
// this is the class extension, where you define
// the "protected" properties and methods of the class
#interface BaseClass ()
// foo is now readwrite
#property (nonatomic, readwrite) NSString *foo;
// bar is visible to implementation of subclasses
#property (nonatomic, readwrite) int bar;
-(void)baz;
#end
#endif
BaseClass.m
// this will import BaseClass.h
// with BaseClass_protected defined,
// so it will also get the protected class extension
#define BaseClass_protected
#import "BaseClass.h"
#implementation BaseClass
-(void)baz {
self.foo = #"test";
self.bar = 123;
}
#end
ChildClass.h
// this will import BaseClass.h without the class extension
#import "BaseClass.h"
#interface ChildClass : BaseClass
-(void)test;
#end
ChildClass.m
// this will implicitly import BaseClass.h from ChildClass.h,
// with BaseClass_protected defined,
// so it will also get the protected class extension
#define BaseClass_protected
#import "ChildClass.h"
#implementation ChildClass
-(void)test {
self.foo = #"test";
self.bar = 123;
[self baz];
}
#end
When you call #import, it basically copy-pastes the .h file to where you are importing it.
If you have an #ifdef, it will only include the code inside if the #define with that name is set.
In your .h file, you don't set the define so any classes importing this .h wont see the protected class extention.
In the base class and subclass .m file, you use #define before using #import so that the compiler will include the protected class extension.
While the other answers are correct, I'd like to add...
Private, protected and public are available for instance variables as such:
#interface MyClass : NSObject {
#private
int varA;
#protected
int varB;
#public
int varC;
}
#end
Your only choice is to declare it as public in the header file. If you want to at least keep some method separation, you can create a category and have all your protected methods and attributes there, but in the end everything will still be public.
#import "MyClass.h"
#interface MyClass (Protected)
- (void) protectedMethods;
#end
Simply create a .h file with your class extension. Import this into your .m files. Incidentally, this is a great way to test private members without breaking encapsulation (I'm not saying you should test private methods :) ).
// MyClassProtectedMembers.h
#interface MyClass()
#property (nonatomic, strong) MyPrivateObject *privateObject;
- (void) privateMethod;
#end
/////////////////
#import "MyClassProtectedMembers.h"
#implementation MyClass
// implement privateMethod here and any setters or getters with computed values
#end
Here's a gist of the idea: https://gist.github.com/philosopherdog/6461536b99ef73a5c32a
I see good answers for making properties visible, but I don't see exposing the methods addressed very clearly in any of these answers. Here is how I have successfully exposed private methods to the subclass using a Category:
SomeSuperClass.m:
#implementation SomeSuperClass
-(void)somePrivateMethod:(NSString*)someArgument {
...
}
SomeChildClass.h
#interface SomeChildClass : SomeSuperClass
SomeChildClass.m
#interface SomeSuperClass (exposePrivateMethod)
-(void)somePrivateMethod:(NSString*)someArgument;
#end
#implementation SomeChildClass
-(void)doSomething {
[super somePrivateMethod:#"argument"];
}
#end
That's because there's not even a real distinction between private and public. While the compiler may warn you about an interface missing a certain method or instance variable, your program will still work.

Public iVar; readonly from other classes

What is the best way to make an iVar writeable by its owning class, but readonly by other classes?
Is there more than one way?
The only way I can think of is to set a #property (readonly) for the iVar, but not use dot notation inside the owning class (which I'm guessing wouldn't work with readonly), and in the owning class just reference it directly, without dot notation, then in other class, reference it with dot notation.
But I'm curious if there are other methods.
You can make a property read/write just for the implementation. You do this using a class extension, or anonymous category, in your implementation. Easier to demonstrate so, for example, in your .h:
#interface MyClass
#property (readonly) NSInteger age;
...
#end
and in your .m:
#interface MyClass () // class extension/anonymous category for private methods & properties
// implementation of these go in main #implementation
#property (readwrite) NSInteger age;
...
#end
#implementation MyClass
#synthesize age;
...
#end
Now you can use the property within your class read/write and from outside as read-only.
You do the same for private methods.
[Note: This is Objective-C so the above isn't bullet proof - there are ways around it to call the properties setter - but the compiler will flag errors which assign to the property from outside the class.]
After comments:
[Note 2: an anonymous category/class extension is very similar to a named category. The former must be implemented in the main implementation, the latter may be implemented in an #implementation classname (categoryname) or in the main implementation. Furthermore only the main interface, the interface for a class extension/anonymous category, and the main implementation may declare instance variables; interfaces and implementations for named categories may not. Properties may be declared in both anonymous and named categories, however they may only be synthesized in the main implementation and not in named category implementations. This note is correct at press time, some of these features have changed as Objective-C/Xcode develops.]
Use the private specifier for ivars and a class extension to define the accessor - that way the ivar is private to the class.
// FooClass.h
#interface FooClass : NSObject {
#private int boo;
}
#end
// FooClass.m
#interface FooClass () {
}
#property (nonatomic,assign) int boo;
#end
#implementation FooClass
#synthesize boo;
// ....
#end

Varieties of #interface declarations, some with parentheses

I've noticed a variety of #interface declarations for Objective-c classes. I'd like to understand why developers declare #interface in the following ways:
// in the .h file
#interface MyClass : NSObject
// ...
#end
// in the .m file (what's the purpose of the parens?)
#interface MyClass ()
// more property declarations which seem like they can go in the .h file
#end
// again in the .m file (what's the purpose of private?)
#interface MyClass (Private)
// some method declarations
#end
This is just a normal class interface, inheriting from NSObject, where you declare ivars, properties and methods
// in the .h file
#interface MyClass : NSObject
// ...
#end
The following two are categories, which allow you to add methods to a class. It is not a subclass however (do not declare a method with the same name, as you won't be able to access the original one). If you have a named category of the interface (like #interface MyClass (Private)), then the implementation should be provided in #implementation MyClass (Private), in the case of unnamed categories (also called extensions), the implementation can be provided as usual. Note that extensions also allow you to add ivars to the class while (named) categories do not.
// in the .m file (what's the purpose of the parens?)
#interface MyClass ()
// more property declarations which seem like they can go in the .h file
#end
// again in the .m file (what's the purpose of private?)
#interface MyClass (Private)
// some method declarations
#end
It is used to declared private methods.
This response explain this in details: What are best practices that you use when writing Objective-C and Cocoa?
What ever goes in the .m file is private. the parens are for categories so you can segment your code into categories to make it more readable. because the code is in .m and private, they called the category Private.