Why is there another #interface inside the.m file? [duplicate] - ios

This question already has answers here:
Difference between #interface definition in .h and .m file
(3 answers)
Closed 10 years ago.
Sometimes I see another interface declaration like this:
#interface MyCode ()
#end
Isn't this duplicating the one in the .h file?

That is a category provided by Xcode and is used to declare private properties and methods that are only usable from within this implementation file.
You won't always want to expose all of the methods from your class to the outside world, and instead you would declare them in this private category (I always prefix these private methods with an underscore (_) to make it obvious I am calling a private method, but that is entirely optional).
As an example, here is a private intialization method that I don't want exposed:
#interface MyClass ()
- (BOOL)_init;
#end
#implementation MyClass
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self != nil)
{
if (![self _init])
self = nil;
}
return self;
}
- (id)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:code];
if (self != nil)
{
if (![self _init])
self = nil;
}
return self;
}
- (BOOL)_init
{
self.something = whatnot;
self.thingA = self.thingB;
return YES;
}

it is used when you want to declare private ivars/properties/methods.

In .h file you've got public methods and properties, and in .m file you have private.

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. See the discussion of private class extensions in the Programming with Objective-C guide.

This #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 (in this #interface()) unless an instance of the class needs to access them.
Hope this helps

It's a class extension. Read more
Usually used for declaration private ivars/properties/methods.

Related

Why does a constant property may get initialized twice in a Swift class?

The project I'm working on is a mix of Swift and Objective-C. Here's the snippet:
// ViewController.m
#interface ViewController ()
#property (nonatomic, strong) MyModel *model;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.model = [[MyModel alloc] initWithIntValue:10];
}
// MyModel.swift
fileprivate class SomeProperty {
init() {
print("SomeProperty init")
}
}
class MyModel: BaseModel {
private let property = SomeProperty()
}
// BaseModel.h
#interface BaseModel : NSObject
- (instancetype)initWithIntValue:(int)intValue;
- (instancetype)initWithIntValue:(int)intValue doubleValue:(double)doubleValue;
#end
// BaseModel.m
#implementation BaseModel
- (instancetype)initWithIntValue:(int)intValue doubleValue:(double)doubleValue {
if (self = [super init]) {
}
return self;
}
- (instancetype)initWithIntValue:(int)intValue {
return [self initWithIntValue:intValue doubleValue:0];
}
#end
Interestingly, I find when MyModel instance is initialized, SomeProperty init will be printed twice, which means two SomeProperty instances are created. What's worse, Debug Memory Graph shows that there is a SomeProperty object memory leak. So why is this and how can I fix it?
Rewrite BaseModel.h like this:
- (instancetype)initWithIntValue:(int)intValue;
- (instancetype)initWithIntValue:(int)intValue doubleValue:(double)doubleValue NS_DESIGNATED_INITIALIZER;
Note the NS_DESIGNATED_INITIALIZER marker at the end of the second initializer. (You may have to scroll my code in order to see it.)
This marker, aside from what it does within Objective-C (in its role as a macro), tells Swift that both initializers are not designated initializers; rather, Swift concludes, the first one is a convenience initializer. And that is correct; it calls another initializer, namely — in this case — the designated initializer.
Without that NS_DESIGNATED_INITIALIZER markup, Swift interprets the situation incorrectly because of the (already rather complicated) relationship between Swift initializers and Objective-C initializers. It thinks both initializers are designated initializers and you get this curious double initialization from Swift.

instance variables in objective c .m file

In Objective c, what is the differences between instance variables var1 and var2 showing below?
(This code is in one .m file, does it make any difference if the #interface is in a header file & #implementation is in implementation file? I mean any difference comparing with that in one file regarding to the two instance variables.)
#interface MyService {
NSString *var1;
}
#end
#implementation MyService {
NSString *var2;
}
#end
The difference between them is visibility. The variable defined in the #interface section is visible to any code which imports the interface. The variable declared in the #implementation section is only visible to code within the class implementation.
If the #interface is declared in the implementation file, it will act, for all practical purposes, the same as declaring it in the #implementation section.
Instance variables declared in the implementation are implicitly
hidden (effectively private) and the visibility cannot be changed -
#public, #protected and #private do not produce compiler errors (with
the current Clang at least) but are ignored.
you can found it here
I have deep searched for your question.Well asked Leem.fin brother.I tried sample one
#import "SecondViewController.h"
#interface SecondViewController ()
{
NSString *variableOne;
}
#end
#implementation SecondViewController
{
NSString *variableTwo;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[self setValueToString];
NSLog(#"The variable One is - %#",variableOne);
NSLog(#"The variable Two is - %#",variableTwo);
}
-(void)setValueToString
{
variableOne = #"iOS";
variableTwo = #"iPhone";
}
The printed results are
The variable One is - iOS
The variable Two is - iPhone
But when I tried to access these in Class method
+(void)changeStrings
{
variableOne = #"iPad"; //I get error here
variableTwo = #"iMac"; //I get error here
}
The error shows
Instance variable 'variableOne' accessed in class method
Instance variable 'variableTwo' accessed in class method
From above code I understood
Both are instance variables
That can be accessed only in instance methods
There is no difference between them
So Where to put
Difference between them
Difference between putting variable inside interface and implementation

Objective C - Declaration Error - please explain

#interface Connections()
{
static Connections *this;
}
#end
The above piece of code in .m file throwing compiler error
Type name does not allow storage class to be specified
at the same time when the
static
key word is removed it works well - which so obvious.
Purpose : I want "Connections" instance static and private.
Why is this behavior, please help.
You cannot declare class-level variables in Objective-C classes; instead you need to "hide" them in the implementation file, often giving them static-scope so they cannot be accessed externally.
Connections.m:
#import "Connections.h"
static Connections *_sharedInstance = nil;
#implementation Connections
...
#end
And if this is a singleton, you typically define a class-level accessor to create the singleton upon first use:
+ (Connections *)sharedInstance
{
if (_sharedInstance == nil)
{
_sharedInstance = [[Connections alloc] init];
}
return _sharedInstance;
}
(and you'll need to add the declaration in the .h file):
+ (Connections *)sharedInstance;

How to call method from one class in another (iOS)

This a very basic question but I've searched all over and been unable to find an answer that explains well enough for me to get my head around it.
What I want to do is create a method in one class of my iOS app and then call that method from other classes in my app. Could someone explain exactly what I need to do to achieve this? Any help would be greatly appreciated as all my attempts so far have failed!
Thanks.
Objective-C:
You have to import the header of the class that contains the method you want to use (ClassYouWantToUse.h) into the class you want to use it at (TargetClass).
Inside the TargetClass.h or TargetClass.m (depending on the scope you want to give it):
#import "ClassYouWantToUse.h"
Then create an instance of the class you want to use inside the target class either as a property like this:
#property (nonatomic,strong) ClassYouWantToUse *classObject;
Or as an instance variable like this:
ClassYouWantToUse *classObject;
Make sure you initialize it! (usually inside ViewDidLoad):
classObject = [[ClassYouWantToUse alloc] init];
Now you can call any public methods from that class like this:
[classObject theClassMethodWithParam:param1 andSecondParam:param2];
Note: The ClassYouWantToUse class must have the methods that you want to make accessible to others by declaring them in the header file:
- (void)theClassMethodWithParam:(UIImage*)someImage andSecondParam:(NSString*)someText;
Otherwise you won't be able to see these methods.
Swift:
Theres really nothing special about it in swift, just adding this as a reference.
In swift you simply create an instance of the class you want to use:
let classObject = ClassYouWantToUse()
And use it directly:
classObject.theClassMethodWithParam(param1, andSecondParam:param2)
You have two basic options. You can either create or pass-in an instance of the first class to the second class, or you can add a static method to the first class and call it directly using the class object.
For instance, say you have:
#interface ClassA : NSObject {
}
//instance methods
- (int) addNumber:(int)num1 withNumber:(int)num2;
//static/class methods
+ (int) add:(int)num1 with:(int)num2;
#end
#implementation ClassA
- (int) addNumber:(int)num1 withNumber:(int)num2 {
return num1 + num2;
}
+ (int) add:(int)num1 with:(int)num2 {
return num1 + num2;
}
#end
Then you can do:
#import "ClassA.h"
#interface ClassB : NSObject {
ClassA* adder;
}
//constructors
- (id) init; //creates a new instance of ClassA to use
- (id) initWithAdder:(ClassA*)theAdder; //uses the provided instance of ClassA
//instance methods
- (int) add2To:(int)num;
//static/class methods
+ (int) add3To:(int)num;
#end
#implementation ClassB
- (id) init {
if (self = [super init]) {
adder = [[ClassA alloc] init];
}
return self;
}
- (id) initWithAdder:(ClassA*)theAdder {
if (self = [super init]) {
adder = theAdder;
}
return self;
}
- (int) add2To:(int)num {
return [adder addNumber:2 withNumber:num];
}
+ (int) add3To:(int)num {
return [ClassA add:3 with:num];
}
#end
Note that in most cases, you would use instance methods rather than static methods.
You have to use the concept of delegation.
https://developer.apple.com/library/ios/#documentation/General/Conceptual/CocoaEncyclopedia/DelegatesandDataSources/DelegatesandDataSources.html

What does "#private" mean in Objective-C?

What does #private mean in Objective-C?
It's a visibility modifier—it means that instance variables declared as #private can only be accessed by instances of the same class. Private members cannot be accessed by subclasses or other classes.
For example:
#interface MyClass : NSObject
{
#private
int someVar; // Can only be accessed by instances of MyClass
#public
int aPublicVar; // Can be accessed by any object
}
#end
Also, to clarify, methods are always public in Objective-C. There are ways of "hiding" method declarations, though—see this question for more information.
As htw said, it's a visibility modifier. #private means that the ivar (instance variable) can only be accessed directly from within an instance of that same class. However, that may not mean much to you, so let me give you an example. We'll use the init methods of the classes as examples, for simplicity's sake. I'll comment inline to point out items of interest.
#interface MyFirstClass : NSObject
{
#public
int publicNumber;
#protected // Protected is the default
char protectedLetter;
#private
BOOL privateBool;
}
#end
#implementation MyFirstClass
- (id)init {
if (self = [super init]) {
publicNumber = 3;
protectedLetter = 'Q';
privateBool = NO;
}
return self;
}
#end
#interface MySecondClass : MyFirstClass // Note the inheritance
{
#private
double secondClassCitizen;
}
#end
#implementation MySecondClass
- (id)init {
if (self = [super init]) {
// We can access publicNumber because it's public;
// ANYONE can access it.
publicNumber = 5;
// We can access protectedLetter because it's protected
// and it is declared by a superclass; #protected variables
// are available to subclasses.
protectedLetter = 'z';
// We can't access privateBool because it's private;
// only methods of the class that declared privateBool
// can use it
privateBool = NO; // COMPILER ERROR HERE
// We can access secondClassCitizen directly because we
// declared it; even though it's private, we can get it.
secondClassCitizen = 5.2;
}
return self;
}
#interface SomeOtherClass : NSObject
{
MySecondClass *other;
}
#end
#implementation SomeOtherClass
- (id)init {
if (self = [super init]) {
other = [[MySecondClass alloc] init];
// Neither MyFirstClass nor MySecondClass provided any
// accessor methods, so if we're going to access any ivars
// we'll have to do it directly, like this:
other->publicNumber = 42;
// If we try to use direct access on any other ivars,
// the compiler won't let us
other->protectedLetter = 'M'; // COMPILER ERROR HERE
other->privateBool = YES; // COMPILER ERROR HERE
other->secondClassCitizen = 1.2; // COMPILER ERROR HERE
}
return self;
}
So to answer your question, #private protects ivars from access by an instance of any other class. Note that two instances of MyFirstClass could access all of each other's ivars directly; it is assumed that since the programmer has complete control over this class directly, he will use this ability wisely.
It important to understand what it means when somebody says that you can't access a #private instance variable. The real story is that the compiler will give you an error if you attempt to access these variables in your source code. In previous versions of GCC and XCode, you would just get a warning instead of an error.
Either way, at run time, all bets are off. These #private and #protected ivars can be accessed by an object of any class. These visibility modifiers just make it difficult to compile the source code into machine code that violates the intent of the visibility modifiers.
Do not rely on ivar visibility modifiers for security! They provide none at all. They are strictly for compile-time enforcement of the class-builder's wishes.

Resources