Private and protected #interface in objective c [duplicate] - objective-c

This question already has answers here:
Varieties of #interface declarations, some with parentheses
(3 answers)
Closed 8 years ago.
I'm looking at a .h file for an Objective-C class and I see multiple interface declarations in it and I am unsure as to what the differences are and what they mean.
First I see
#interface TAModel : NSObject
Which I recognize. TAModel is the class and NSObject is it's super class. What I'm confused about is further down I see another interface declaration:
#interface TAModel (Protected)
Also inside another .m file (unrelated to the first two) I have seen:
#interface TAWorker (Private)
I was wondering what the second two mean, what they are doing. As far as I know with objective-c there is no true protected visibility between classes.

It's creating a category class in which they're putting their protected/private members. The usual idiom is just to create a class extension (so you'll often see #interface Foo (); the difference here is that you can also declare more fields, not just properties and methods) in the .m file.
Neither way of doing this truly protected or private as you can still technically get at the things declared there by casting to id first or through one of the performSelector: methods. But it's pseudo-private because you don't publish the interface publicly if it's not in the .h file.

Related

What does this syntax mean relating to interface declaration?

This is from the ViewController.m file in a starter project from a tutorial for a game.
#interface ViewController()
//irrelevant stuff omitted
#end
It's the ViewController() bit that confuses me. I understand the different between public and private interfaces, but I haven't used a private interface til now in Objective-C. I'm used to seeing something like this instead, for the public interface:
#interface ViewController : UIViewController
So why now is it just the first one, and with parentheses, with no inheritance notation?
That's a class extension. It allows for declaring additional interface, usually private because it's in an implementation (.m) file. It's similar to a category, except that the compiler will require you to supply the implementation for any interface declared within it. (A category can declare an interface even if nothing provides any implementation.)

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).

Objective-c declaring method [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Private Method Declaration Objective-C
I assumed in objective-c class methods need to be declared either in the .h file which makes them publicly visible or in the .m file using class extension to make it more private.
I thought without first declaring the method, xcode would complain, however I add a method to my main AppDelegate class without declaring it, and everything works fine.
What part have I confused, should I be declaring all methods of the class or is it okay not to if the method will only be used by that class and no where else??
You declare methods anyway. Either in .h file
#interface ViewController : UIViewController
-(void)myMethod;
#end
or in private interface in .m
#import "ViewController.h"
#interface ViewController ()
-(void)myMethod;
#end
Declaration of all class methods is not necessary in .h file.
Declare only those methods in .h file which you want to make publicly accessible to others.
Objective C is very dynamic language, and it resolves methods at runtime. That's why we're sending messages to objects and not invoking methods (like for example in C++). So if compiler doesn't see method declaration it doesn't mean that object can't find it at runtime.
So you can actually define ObjC methods everywhere you want (in any file or even in different libraries). Ones the program is compiled and linked ObjC runtime can find all of them.

Is the use of instance variables discouraged? [duplicate]

This question already has answers here:
Must every ivar be a property?
(4 answers)
Closed 9 years ago.
Lately, it seems that explicitly declared instance variables in Objective-C are considered a thing to avoid, with the preference being to use "private" properties, i.e., properties declared in a class extension in the .m file.
The last example of this is the WWDC '12 presentation on advances in Objective-C.
What I haven't been able to find is a rationale for this preference, and I have searched a lot. It obviously provides a sort of solution to the fragile base class problem, but that was already solved with Objective-C 2.
Is there some crucial piece of documentation that I have missed, or is there a simple explanation that a kind soul could provide here?
You mean this?
#interface Foo : NSObject {
float bar;
id baz;
}
If those instance variables are not a part of the public interface, you will do better to move them into the implementation file, either as declared properties in a class extension or to the #implementation block:
#interface Foo ()
#property(assign) float bar;
#property(strong) id baz;
#end
…or:
#implementation Foo {
float bar;
id baz;
}
This way the public interface declared in the header stays simple and changes in the implementation won’t force a recompilation of all the source files that import the header.

Purpose of Obj-c categories in a specific situation.

I'm quite new at Objective-C and i've a question :
I've been through some Apple's sample code and found the following :
https://developer.apple.com/library/ios/#samplecode/GLSprite/Listings/Classes_EAGLView_m.html#//apple_ref/doc/uid/DTS40007325-Classes_EAGLView_m-DontLinkElementID_4
In the top of the file, I found to uses of Objective-C categories
#interface EAGLView (EAGLViewPrivate)
- (BOOL)createFramebuffer;
- (void)destroyFramebuffer;
#end
#interface EAGLView (EAGLViewSprite)
- (void)setupView;
#end
Just after that, starts the implementation of the EAGLView class.
What is the real purpose of categories here, as the 3 functions above could also be defined directly in the header file ??
Thx
As indicated by the first category's name ("EAGLViewPrivate") declaring these methods in the .m file is a way of simulating private methods. Objective-C doesn't have true support for private methods, but since these aren't declared in the .h file, the compiler will warn when code outside the .m file where they're declared tries to call them.
This is more commonly done with class extensions (a special case of a category) these days, mostly because using a class extension results in the compiler warning if a "private" method isn't implemented in the class's #implementation block. Class extensions were a new feature in Objective-C 2.0, so in older code, you'd often see a category with private in the name as in the code you've posted. The intent is the same.