How to declare protocol in separate header file - objective-c

I have two classes. Both these classes are delegates of each other. This gives me error like "Can not find protocol declaration". After searching on net, I came to the conclusion that, this is the case of cyclic dependency.
To break this dependency the solution they have suggested is to define protocol in another header file. I could not find any tutorial on how to do this and how will it affect my code?

I have a example for you..
#class ClassA;
#class ClassAController;
#protocol CreateClassADelegate
-(void)CreateClassA:(ClassAController *)sender didCreateClassA:(ClassA *)ClassAObj;
-(void)CreateClassACancel:(TSInputController *)sender;
#end

Check #Toro's answer in this previous SO question
UIViewController calling each other's delegate

In case you are using XCode 4 you just creating new file as always, the difference is that you need to choose Objective-C protocol in Cocoa Touch section rather then Objective-C class or UIViewController subclass.
Other approach you may use is to create new Objective-C class and then just delete the .m file manualy and change #interface to #protocol in .h file.

Related

Objective-C. Class conforming to a protocols of an UICollectionView

I have this Custom subclass of UIViewController where I've built an UICollectionView.
I am conforming to a CollectionViewDelegates and CollectionViewDataSource in that UIViewController.
Then Xcode asks me to put all the stubs that are needed. There is a lot of stubs. When I worked with Swift, I've added few stubs that I needed like numbersOfItemsInSection or didSelectRowAt. Now I've got over 10. To be completely honest, at this stage I would not even know what is the functionality of most of them. I will figure that out, but my main question is, do I need to use all of them? Or can I just delete them and forget about them right now? Some of them are:
didUpdateFocusInContext
viewWillTransitionToSize
systemLayoutFittingSizeDidChangeForChildContentContainer
etc.
Right click the delegate name in the .h file and jump to the definition. You require all methods not explicitly marked as #optional
I didn't check it for your example but here is a generic one
#protocol MyProtocol
- (void)requiredMethod;
#optional
- (void)anOptionalMethod;
- (void)anotherOptionalMethod;
#required
- (void)anotherRequiredMethod;
#end

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

ios multiple class implementation

I came from front-end development, so MVC and OOP still give me some head shakes. Just to explain to you I send like 500 dicionaries (with 100 parameters) to a nodejs server. The problem is that I has creating ivars for each parameter and each dicionary. Now I want to create some classes like a person class, in the same header file that I have my syncronization class for example. I can make something like this on the header:
#import <Foundation/Foundation.h>
#import "GCDAsyncSocket.h"
#class GCDAsyncSocket;
#interface socketDelegate : NSObject<NSStreamDelegate>
{
NSInputStream *inputStream;
NSOutputStream *outputStream;
NSMutableArray *messages;
GCDAsyncSocket *socket;
dispatch_queue_t connectionQueue_;
}
- (void) initNetworkCommunication;
- (void) sendMessage:(NSArray *)message:(int)numberOfContactsToSend;
#end
#interface personInfo: NSObject
#property (nonatomic,weak)NSString*firstName;
#property (nonatomic,weak)NSString*lastName;
#property (nonatomic,weak)NSDictionary*dicToSendWithConctactInfo;
#end
But in the implementation I don't know how to handle the multiple classes. Like I've a method inside the "socketDelegate" class that needs to use the person class, but it's not available inside it.
What's the best way to implement this?
To answer your immediate question, you can just forward-declare personInfo at the top of the file before socketDelegate:
#class personInfo;
Usually you just put each public class in its own implementation and header files, and each implementation file includes the header files of all the classes it uses. The header files usually just need to forward declare the classes they refer to (as you are doing with #class GCDAsyncSocket;. However, it doesn't make sense that you are both importing #import "GCDAsyncSocket.h" and forward-declaring. From what you are using it for here, you don't need the import. However, to properly use GCDAsyncSocket, you will need to implement GCDAsyncSocketDelegate protocol, which will require you to import the header; however, you should probably implement that protocol as part of a "class extension" inside the implementation file).
You only need to import the header of something in your header if you are subclassing a class, or implementing a protocol that is declared in the header. For all other uses (i.e. using the class or protocol as part of a pointer type), you can simply forward-declare it. (And for implementing a protocol, you can do that in the implementation file with a "class extension" if you don't need people to know you're implementing the protocol.
Different classes should, typically, be in different files. Once PersonInfo (please capitalize class names) has it's own PersonInfo.h and PersonInfo.m, then you simply add
#import "PersonInfo.h"
to the header file above to be able to reference PersonInfo from your SocketDelegate class (again, please capitalize class names).

how to access a newly created class in objective c

I get the feeling that this is a very stupid question, but I cannot find an answer anywhere. I've created a new class in an XCode project called "Word", with its own .h and .m files, which inherits from NSString, and has its own declared instance variable, method, etc. How do I access it within the viewcontroller.h and .m files? I though it would just show up in the little suggestion box in XCode, like the pre-made classe, but it doesn't. How do I use my new class?
#import "Word.h"
I will note that subclassing NSString is extremely uncommon and almost never what you mean to do. You probably meant to have Word have an NSString property.
in your .h, at the top type #import " then start typing Word.h. It should autocomplete if the .h and .m files are in your project correctly.
You just need to add the following to your ViewController.h
#import "Word.h"

"Cannot find interface declaration error..." after #class

I've run into an Objective-C problem that doesn't seem to make any sense to me. I am a relatively well-versed ObjC programmer and understand the whole "forward declaration" concept, but this one has me scratching my head. So here's the deal:
ClassA is a class in my Xcode project that is project-only.
ClassB is a subclass of ClassA which is public and is imported into my framework's header.
I am getting a "Cannot find interface declaration for 'ClassA', superclass of 'ClassB'..." error when building. I have already put the #class ClassA; forward declaration in ClassB.h, but that does not seem to solve the problem. When I change the #class ClassA; to #import ClassA.h, it works fine. However, since ClassA is project-only, dependent projects cannot build ClassB because it cannot access ClassA's source.
Any help would be appreciated and I hope that makes sense. Thanks!
The problem is that you have an infinite loop in your #imports.
The solution: all #imports go in the implementation file and all classes needed are declared in the .h files.
To subclass a class, the superclass's full declaration must be available to the compiler. #class just enables references to instances of said class -- allows for A *foo;.
Subclassing requires more metadata (at least, it did under the legacy runtime -- I think it might be possible to support subclassing without the full super's #interface. Technically possible, but probably not useful.)
I have an answer: You must check your '#import' order. Before you use the superclass it should be imported and compiled.
I had an issue where I was using categories in a superclass method and was getting this inheritance error. Once I moved the categories .h imports to the superclass .m file thing started getting better.
Just carry out all possible headers from .h to .m file of superclass and see which one is the matter of the problem. I'm sure that it's one of common headers used in both classes.
Like #Igor said, the order of imports matters:
I had to change
#import <KeychainItemWrapper/KeychainItemWrapper.h>
#import <Foundation/Foundation.h>
to
#import <Foundation/Foundation.h>
#import <KeychainItemWrapper/KeychainItemWrapper.h>