How to send a message from an instance method to a object of another class - objective-c

I tried to search for an answer about this (simple) question but nothing seems to work well, even books are not so specific (atleast the books I've read), or probably I'm simply missing something important, since I'm a little bit confused I've decided to try here.
Here's the question:
Say that I have a ClassA which contains one or many instance variables.
Then I have a ClassB which contains an Instance Method that modify ClassA variable (is this possible right?) the classes have NOT inheritance from each other, both inherits from NSObject
Then I want to call the method of the ClassB over the ClassA object on the UIViewController. I believe I need a reference between classes but i'm not sure on how to set them to make them works. Imagine I have a Paper which contains writes or numbers (in this case numbers) and a class erase to modify it's variable and erase numbers (for example by subtracting).
here's some code:
Paper.h
#interface Paper : NSObject
#property (nonatomic) int numbers;
#end
Paper.m
#import "Paper.h"
#implementation Paper
#synthesize numbers;
#end
and Eraser.h
#interface Eraser : NSObject
-(void)eraseMethod;
#end
Eraser.m
#import "Eraser.h"
#implementation Eraser
-(void)eraseMethod {
//here I want to make a subtraction of the ivar declared in Paper
}
#end
and finally I'm trying to call it on the UIViewController like so
[paperObject eraseMethod];
I tried by declaring #class in each files as I've read somewhere but this won't help in any way... I hope this is clear as question

Ivars are just storage slots and they are private to the class when without specifying access conditions.You can use property for the purpose of accessing from another class. more info here
in order to achive what you speak of,make the method a class method
see here
#import "Eraser.h"
#implementation Eraser
+(void)eraseMethod {
//here I want to make a subtraction of the ivar declared in Paper
}
#end
thus you can achieve the method in your VC.

Related

Objective-C #interface and #implementation clarification

I'm still fairly new to Objective-C but I'd love to learn more about how it should be done.
I'm building a simple cheat sheet that I'd like to print and put on my office wall as a reminder.
Here's what I have so far:
// Headers (.h)
// Shows what's available to other classes
#interface ExampleViewController : UIViewController
// Declare public methods, ivars &
// properties that are synthesized.
#end
// Implementation (.m)
// Defines the content of the class
#interface ExampleViewController ()
// Class extension allowing to declare
// private methods, ivars & properties that are synthesized.
#end
#implementation ExampleViewController
// Private Properties
// Method definitions
#end
One thing I don't understand is why have both #interface and #implementation inside the implementation .m file?
I get that we can declare private stuff but why not simply throw them in #implementation like:
#implementation ExampleViewController
UIView *view; // private property
- (void)...more code
#end
#1 - Why should I ever use #interface from within my implementation .m file?
#2 - For header .h, why should I ever use #class more than #import?
#import actually gets the whole definition and #class tells the compiler that the symbol is a class. So I just don't see why I should ever use #class?
#3 - Otherwise, is there anything I should be adding somewhere in my .h or .m cheat sheet?
That's not a problem-related question but a more wiki-esque question so we everybody can look it up and completely and quickly understand those concepts as they are very hard to grasp for any newcomer.
Why should I ever use #interface from within my implementation .m file?
Because it's better to clearly separate public and private parts of the class.
For header .h, why should I ever use #class more than #import?
When forward-declaring classes for use in protocols. Like this:
#class Foo;
#protocol FooDelegate
// this wouldn't compile without a forward declaration of `Foo'
- (void)fooDidFinishAction:(Foo *)f;
#end
Otherwise, is there anything I should be adding somewhere in my .h or .m cheat sheet?
That's way too general to be answered in one post.
1 - Why should I ever use #interface from within my implementation .m file?
When you do not intend to expose that interface to any other component. That's certainly the case for private class extensions but may also apply for something like a test which doesn't need a .h file at all because while it does define a class it does not need to expose an interface for any other component to use.
2 - For header .h, why should I ever use #class more than #import?
Invert your question; why should I ever use #import rather than #class?
#class informs the compiler that a class definition of that name will exist to be linked but says nothing about it's interface.
#import makes the class' interface available to you.
A forward declaration requires less work and can allow for faster builds. It is also not always possible to #import a class at all times (as in circular references like #H2CO3's protocol example). If all you need to know is that a class exists then just use the forward declaration. When you actually need to interact with its specific interface (usually in your class' implementation) then you need to #import.
3 - Otherwise, is there anything I should be adding somewhere in my .h or .m cheat sheet?
Unless you intend to actually expose ivars as a public interface (almost certainly not the case) leave them out of your .h and expose only properties instead.
Keep your public interface as simple as possible. Try not to reveal implementation details. However keep it informative enough that users of the class can verify its behavior using that public interface. (I find test driving the design of the class using only it's public interface a good tool for striking this balance.)
Imports and forward declarations expose dependencies. Keep them to the minimum you actually need so that you can understand what the class in question actually depends on.
Delegate protocols and block types are a common part of a class' interface but not part of the #interface. Include them in the .h if they are needed by other classes (e.g. to register callbacks).

Why is there #interface above #implementation?

I am wondering why there is twice #interface. One in class.h and other in class.m. For example:
TestTableViewController.h:
#import <UIKit/UIKit.h>
#interface TestTableViewController : UITableViewController
#end
and (automatically generated) class.m i find:
#import "TestTableViewController.h"
#interface TestTableViewController ()
#end
#implementation TestTableViewController
... methods delegated from UITable delegates
#end
So my question is, what the #interface TestTableViewController () in the .m file is about. Why it is there? Do I need it?
Thanks in advance
The second #interface directive is in the implementation file (.m) -- you can infer from it that it's meant for declaring stuff that the creator of the class didn't want to expose to the user of the class. This usually means private and/or internal methods and properties. Also note that there are two types of doing this. The one (which you see here) is called a "class extension" and it's denoted by an empty pair of parentheses:
#interface MyClass ()
This one is particularily important because you can use this to add additional instance variables to your class.
The second one, called a "category", is indicated by a non-empty pair of parentheses, enclosing the name of the category, like this:
#interface MyClass (CategoryName)
and it's also used to extend the class. You can't add instance variables to a class using categories, but you can have multiple categories for the same class, that's the reason why it's mainly used to extend system/framework classes for which you don't have the source code -- so a category, in this sense, is the exact opposite of the class extension.
The second "interface" defines an extension for the "TestTableViewController" class, which is not visible to someone who only imports the h file. This is the de-facto way for creating private methods in objective C.
In there you can declare private methods and properties that you only want to use in your class, but not expose to other classes.
The interface in the TestTableViewController.h file is the declaration of a class extension. There are 2 round brackets that show this. The syntax is the same as for writing a category for a class. But in this case it's used to declare some sort of private methods the author does not want to expose in the header file
A normal category interface looks like this:
#interface TestTableViewController (Your_Category_Name)
- (void)doSomething;
#end
And the corresponding implementation:
#implementation TestTableViewController (Your_Category_Name)
-(void)doSomething {
// Does something...
}
#end
In your example there is no category name specified, so it just extends the class and you can implement the method in the normal implementation.
Normally this technique is used to "hide" methods. They are not declared in the header file and are not visible if you only import the .h file.

#interface multiple inheritance?

I am using Objective-C in my app and I have a question about multiple inheritance in #interface declarations.
Pretty much this is what my .h looks like now:
#import "cocos2d.h"
#interface UIViewController (Save)
- (void)saveImage:(UIImage*)image:(NSString*)imageName;
- (void)removeImage:(NSString*)fileName;
- (UIImage*)loadImage:(NSString*)imageName;
#end
#interface CCLayer (Save)
- (UIImage*)loadImage:(NSString*)imageName;
- (BOOL)checkExists:(NSString*)thePath;
#end
So as you can see, I have declared the loadImage method twice. I do not want to do this. This also means I have to have the same code in my .m twice for that method.
Is there any way to mix the UIViewController and CCLayer into 1 #interface so that I do not have to declare it multiple times?
Thanks!
ObjC has no multiple inheritance.
you do not want multiple definitions of the same SEL in the same class.
you could declare (and adopt) a protocol. then you would define the method (loadImage:) in the #interface which declared adoption. you can also declare it in a dummy category, then define loadImage: in another #implementation scope.
an alternative to this is composition -- basically, you would add a class or protocol instance variable to your class and let it perform the work. if this is pubic interface, then you could also provide an accessor to it, or you could wrap it as needed. this is worth consideration if your 50 methods per #interface may be logically subdivided.

What's the difference between adding pseudo-private ivars in a class extension or in the #implementation block?

What's the difference between putting pseudo-private instance variables in a class extension inside the .m file, or putting them in the newly introduced #implementation brackets like shown below?
Are there consequences, pros, cons over one or the other way? Is internal2 treated differently than internal3 in a way a programmer must care of? (of course there is a difference McKay would say but the question is if you care in practice or not).
// MyClass.m
#interface MyClass () {
id internal2;
}
#end
#implementation MyClass {
id internal3;
}
- (void)internalMethod {
NSLog(#"%# %#", internal2, internal3);
}
#end
source: http://www.mcubedsw.com/blog/index.php/site/comments/new_objective-c_features/
The main difference between the two approaches is that you can include the class extension in a separate header, whereas the #implementation ivars obviously have to go with the #implementation block in the .m file (and there can only be one #implementation for a given class (extensions not included)). The practical result of this is that you can have multiple levels of "private" ivars:
MyClass.h: public ivars
MyClass+Private.h: semi-private ivars
MyClass.m: really private ivars
As a hypothetical example, pretend that MyClass is UIView. In that case, UIView.h is the header that we can all access, UIView+Private.h is the "private" header than only Apple can access, and UIView.m has stuff that only the people specifically responsible for UIView need to know about.
Personally, I prefer to put my ivars in a single class extension in the implementation file, I think it's cleaner that way. I don't think there are any performance advantages or consequences to using one or the other, it's more about being able to code the way you want to.

Since when is it possible to declare Objective-C 2.0 properties in a category?

I always thought that one cannot declare an object property in a category.
Until my partner did it in our app's code, and it seemed to work.
I went on a SO and Google binge to try to explain to him that no, Objective-C categories can only be used to add methods, not properties. I found questions such as:
Setting New Property In Category Interface Implementation (look at the accepted answer)
Can I add a property for a method not in my category?
But then I found this link on Apple's site that contains the following about the #property declaration:
A property declaration begins with the
keyword #property. #property can
appear anywhere in the method
declaration list found in the
#interface of a class. #property can
also appear in the declaration of a
protocol or category. (emphasis added)
I know that this doesn't work:
#interface MyClass ()
NSInteger foobar;
- (void) someCategorizedMethod;
#end
But this compiles:
#interface MyClass ()
#property NSInteger foobar;
- (void) someCategorizedMethod;
#end
My question is (a) what's the best practice here? and (b) is this something that is new to Objective-C 2.0, and instead of using a "real" iVar, it simply uses associative storage behind the scenes to make this work?
You have always been able to declare an #property in a category. What you couldn't do -- and still can't -- is declare storage for the property in the category, neither as an instance variable nor via `#synthesize.
However....
#interface MyClass () is not a category. It is a class extension and has a distinctly more specific role than a category.
Namely, a class extension can be used to extend a class's #interface, and this includes #properties that can be #synthesized (including synthesizing storage in the modern runtime).
Foo.h:
#interface Foo
#end
Foo.m:
#interface Foo()
#property int x;
#end
#implementation Foo
#synthesize x; // synthesizes methods & storage
#end
it simply uses associative storage
behind the scenes to make this work?
Nope -- it is a real instance variable. The modern runtime fixes the fragile base class problem.
#interface MyClass ()
NSInteger foobar;
- (void) someCategorizedMethod;
#end
The above doesn't work (as expected) because foobar is, effectively, a global variable.
If you change it to:
#interface MyClass () {
NSInteger foobar;
}
- (void) someCategorizedMethod;
#end
Then it'll work with the latest release of the llvm compiler (with the right flags, as #Joshua indicated in a comment).
Generally speaking, properties are nothing different from other methods. As long as the ivar used is available in the ordinary class, there is no problem at all. It's just syntactic sugar.
Things start to get more difficult if also the ivar is automatically created, as is possible in some configurations.
The main point here is that declaration of the ivar is independent from the property.
Assotiative storage is the solution.
Have a look at this post.