When you start a SplitViewController-based project for the iPad, it creates a DetailViewController. In DetailViewController.h, it declares the interface as normal:
#interface DetailViewController : UIViewController <UIPopoverControllerDelegate, UISplitViewControllerDelegate> {
UIPopoverController *popoverController;
UIToolbar *toolbar;
id detailItem;
UILabel *detailDescriptionLabel;
}
Then, in the implementation file (DetailViewController.m), it declares some other parts of the interface:
#interface DetailViewController ()
#property (nonatomic, retain) UIPopoverController *popoverController;
- (void)configureView;
#end
Why do they do this? What is the point of declaring the interface in two different places/files?
They've created a private category. The methods defined in the .m are only supposed to be used within the .m and are not part of the advertised interface into the DetailViewController. External users of the controller are only expected to call those methods defined in the .h, internal users can also use those in the private category. It is common to also see
#interface DetailViewController (Private)
It's to extend the standard interface with extra methods that you can implement for that specific implementation so that the compiler knows about them.
See Apple's documentation on class extensions for details.
The first is the public interface while the second is a "class continuation" and contains private methods.
Related
I am making a photo upload to Facebook app and I think I need two #interfaces in my .h file for my View Controller.
Here is my ViewController.h file.
#import <UIKit/UIKit.h>
#import <Social/Social.h>
#interface FirstViewController : UIViewController <UIImagePickerControllerDelegate, UINavigationControllerDelegate> {
UIImagePickerController *bailey;
UIImagePickerController *baileys;
UIImage *image;
IBOutlet UIImageView *imageView;
}
- (IBAction)TakePhoto;
- (IBAction)ChooseExisting;
#end
#interface FirstViewController : UIViewController { SLComposeViewController *slComposeViewController;
UIImage *image; }
- (IBAction)ShareFB;
#end
When I try to build this code on to my iPhone or a Emulator it says
/Users/Condrum/Desktop/project/myApp/myApp/FirstViewController.h:21:1: Duplicate interface definition for class 'FirstViewController'
Thanks in advance for the help.
-Condrum.
The pattern is to put a single public interface into the .h file:
#interface FirstViewController : UIViewController
// in here put those public properties and method declarations that
// other classes need to have access to
#end
Then put the second #implementation in the .m file as a private class extension:
#interface FirstViewController () <UIImagePickerControllerDelegate, UINavigationControllerDelegate>
// in here, place those private properties and instance variables that
// only this class needs to be aware of
#end
Note, this second interface uses the () syntax, which indicates that the interface is extending a previously defined interface.
But there's no point in putting both of those interfaces in the same .h file (why have two interfaces; it would be more logical to combine them into one). The primary value of the private class extension is you can extend your interface with details that only the implementation cares about, and avoid cluttering your nice simple public interface. So generally, keep public interface in the .h file, and move the private stuff into the class extension in the .m file.
For more information, see Class Extensions Extend the Internal Implementation.
I now know there is no protected method in Objective-C and here is my problem.
I have two viewControllers with many functions and properties that are shared. My vision was to have a BaseViewController holding the shared methods and properties, and from it two classes will inherit and override the needed functionality while using the same variables,
I don't wish to convert the shared functions to public by placing them in the .h file
To help clarify my question I'm adding code :)
#interface BaseViewController ()
#property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *uiButtons;
- (void)setBtns:(NSArray *)p_btns; //tried with & without this line
#end
#implementation BaseViewController
- (void)setBtns:(NSArray *)p_btns {
uiButtons = p_btns;
//do something generic with the buttons (set font, image etc.)
}
#end
#interface DerivedViewController ()
#property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *buttonsConnectedToTheActualView;
#end
#implementation DerivedViewController
- (void) setBtns:(NSArray *)p_btns {
[super setBtns:p_btns];
//do something specific with the buttons (decide if they face up or down according to this class logic)
}
#end
The call to [super setBtns:p_btns]; raises an error:
DerivedGameViewController.m:No visible #interface for 'BaseViewController' declares the selector 'setBtns:'
How can I achieve this? Can someone post a snippet or point to my mistake (in code or concept).
Just create a second header with the protected methods declared in a category. Name and document the header appropriately.
UIGestureRecognizer.h and UIGestureRecognizerSubclass.h may server you as an example.
I may not have worded the question right, but I am not sure if what I am asking makes 100% so here goes:-)
In Xcode you can set a #class (name of class) above the #interface in the header file.
Is this the same as changing the the UIViewController in the name of the class? See code below:
So is this the same -
#class CoreDataClass;
#interface FlipsideViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
{
}
//This file declares the UITableView
#property (nonatomic, retain) IBOutlet UITableView *mainTableView;
#property (nonatomic, retain) CoreDataClass *cdc;
As this:
#interface FlipsideViewController : CoreDataClass <UITableViewDataSource, UITableViewDelegate>
{
}
//This file declares the UITableView
#property (nonatomic, retain) IBOutlet UITableView *mainTableView;
#property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
#end
??
If this is not the same, how is it different and what are advantages to the different implementation?
The Difference is only really asked if they are similar:-)
#class is not used to create a class, but to forward declare another one. See this question for a good explanation.
They are not the same at all. The first case is a 'forward declaration' - you are telling the compiler that the class CoreDataClass exists, so that you can refer to it in your header file without actually importing the files that define it.
The second case, you are declaring that FlipsideViewController is a subclass of CoreDataClass, and inherits all its methods and instance variables.
They're not even related. The difference is that the superclass ("parent" class) of your view controller will be different (and this can lead to nice unrecognized selector errors...). Forward-declaring a class using the #class keyword is just a convenient way of referring to a class when one doesn't want to import a whole framework header hierarch just in order to refer to one class. I. e., if you don't need to know anyting about a class except that it exists, you can use this keyword. Be careful, however, if you maks heavy use of the class - in those cases, the class forward-declaration is not considered a good solution.
In first case when you use #class it's inform XCode that you will be using CoreDataClass somewhere and you will #import header for example in .m file, in second case you're inherit from CoreDataClass (you will get access to all public and protected properties)
I'm creating an Objective-C category on the UIViewController class. In my project, I want one singular and easy way to get the app delegate.
Here's what I'm doing
// header file UIViewController+AppDelgate.h
#import <UIKit/UIKit.h>
#class ExampleAppDelegate;
#interface UIViewController (AppDelegate)
#property (weak, nonatomic, readonly) ExampleAppDelegate *appDelegate;
#end
// implementation file UIViewController+AppDelegate.m
#import "UIViewController+AppDelegate.h"
#import "ExampleAppDelegate.h"
#implementation UIViewController (AppDelegate)
- (ExampleAppDelegate *) appDelegate {
return (ExampleAppDelegate *)[[UIApplication sharedApplication] delegate];
}
#end
Should I define the property as weak? I think it would be bad to retain this guy as it would normally have retains on view controllers referenced within.
weak/strong in this case is a moot point, since there is no local instance variable holding a pointer. ARC will do the right thing (i.e. it will not send more retains than releases for any given scope).
Why not create a Utility class with a class method that does the same thing, then you can reference it something like:
[Utility appDelegate];
and you wont have to add a property to every single ViewController that needs to access the AppDelegate, the way you currently have it setup.
From the looks of your implementation you dont need to define a property, you only need to declare the method -(ExampleAppDelegate *)appDelegate;
This of course would only work if called on an instance of the class unless you made it a class method.
I'm a little bit confused about the custom UiViewController inheritance.
For example if I have:
#interface MyViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> {
IBOutlet UITableView *tableView;
id <MyDelegate> aDelegate;
AnObject *myObject;
}
#property (nonatomic, assign) id <MyDelegate> aDelegate;
#property (nonatomic, retain) AnObject *myObject;
#end
A subclass of MyViewController "inherits" the protocol declaration? that is, can or not it override the methods in them, setting the delegate and datasource properly without redeclaring in its interface?
And what about property and their possible deallocation?
I would some examples, links...
Firstly, a protocol is simply a promise that a class implements required and (optionally) optional methods. That's all it is. You can override these in subclasses and such however you want.
The data source and delegate of the table view are set to self, and self implements the UITableViewDataSource and UITableViewDelegate protocols.
In your sub-class, self is the sub-class. Overriding the protocol methods in the sub-class will work perfectly fine. The table view is the one defined in the parent class.
In short, the answer is yes. If you want more information I suggest you read up on how #protocol works.