What's the logic of putting #interface in .m file? [duplicate] - objective-c

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Difference between #interface definition in .h and .m file
What is the #interface declaration in .m files used for in iOS 5 projects?
I've seen code like this:
// In Header.h
#interface Header{}
#end
// In Header.m
#interface Header()
#end
My questions are:
What's the difference in putting it in 2 files?
Why put {} after class name in ".h" file and why "()" in ".m" file?

#interface MyClass(){
NSInteger aInt;
}
#property(nonatomic,strong) NSString *name;
#end
is a class extension
with modern compilers this is a great way, to decrale methods, ivars and properties only for private use in the class MyClass.
Class extensions have to be declared in the main implementation file (not in a category).
So you can hide implementation details from the header file, they are private.

This has become a common practice for declaring "private" properties/methods for a given class. By declaring them in an anonymous class extension inside the .m, these properties/methods are not exposed to consuming objects.

Related

Compiling with a circular dependency between methods [duplicate]

This question already has an answer here:
Does Objective-C allow circular dependencies?
(1 answer)
Closed 8 years ago.
I have two classes. Let's call them Dog and Cat.
In Dog I have an instance of Cat, and Dog has a method, harrassCat. Inside harrassCat, I invoke a Cat method, swipeAtDogsNose:, which uses properties of Dog to calculate its output.
The problem is in the header files. I import Cat's header file into Dog and create a property. I then access this property in harrassCat.
For now, I have an NSArray with all the required properties passed as arguments in swipeAtDogsNose:. I want to directly access the properties of Dog within swipeAtDogsNose:, but I cannot import the Dog header into the Cat header because it causes a circular dependency and it fails to compile.
I read on Stack Overflow that when you have circular dependency, you can use #class to access another class. How do I import Dog using #class so that the method declaration in Cat.h looks something like this:
- (BOOL)swipeAtDogsNose:(Dog *)theDog;
What you need is called forward declaration and declare it by just adding the declaration before the interface of the other class in the header file.
#class ClassB;
#interface ClassA
...
Mind that you don't need to do it, you need it just if any method signature requires a type which is not defined and cannot be imported in the header file, if you have a #property of that type or if you have class member of that type.
Basically: if the type name appears in the header then you need to forward declare it (or #import the header), otherwise you can just #import inside .m file. You don't have to import the header inside the other header, importing inside the implementation file is enough.
ClassA:
#class ClassB;
#interface classA
#property (strong, nonatomic) classB* propertyThatUseClassB
#end
ClassB:
#class ClassA;
#interface classB
#property (strong, nonatomic) classA* propertyThatUseClassA
#end

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 !!!

XCode 4.2 why do I see #interface both inside .h and .m files

why do I see #interface twice( inside .h and .m files in this UIViewController files I've created. the one in the .m seems to be like a constructor. is it?
.h file
#interface BlackTimer : UIViewController
#end
.m file
#interface ViewController ()
#end
usually in the .m file you put all the declarations for private methods
it's a good use to write the word "private" (or something similar) like this:
#interface ViewController (private)
-(void)myPrivateMethod;
#end
The #interface in the .m file is called a class extension. Here is a good link explaining it. Hope this helps.
And here is the Apple documentation on class extensions.
The #interface ViewController () definition in the implementation file (.m) is an anonymous Category. It allows to define ivars, properties and messages your class implements without exposing them to other objects importing your public interface (.h).

Declare interface inside implementation file (Objective-C)

In the last verson ox xCode (4.3) I've seen that prefdefined templates (such us Master/Detail template) in which the interface declaration is made in the .m file. For example, in the file MyFile.h there is:
#interface MyFile
#property (nonatomic, retain) NSString *someProp;
#end
And in the MyFile.m file there is:
#implementation MyFile
#interface MyFile {
NSString * anotherProp;
}
- (id) init...
Why it's made on this way? Why the anotherProp isn't declared into the MyFile.h file?
Thanks in advance
Well its not declared this way but this way :-
#interface ClassName() {
Declarations;
}
Methods;
#end
These are called class extension.They are similar to categories but can be declared only in implementation of the class not in any other class.The use of extensions is to redeclare property that is public or readwrite , also declare newer ones , if needed.They simply allow you to declare properties and variables in places other than #interface so the name extensios.
It was inrtoduced to tackle the problem with categories as they make the methods public and data hiding capability of classes is compensated but a class extension effectively extends the class’s primary interface which the declared methods have the same requirements as methods declared in the class’s oft public primary interface.

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.