Protocol definition not found - iphone

I am having a little trouble with getting a protocol definition to work, and this must be a stupid mistake. I included the header in which the definition is located, but I got the warning, so followed the advice to create a separate header file. I still get the warning that the definition cannot be found (when importing this separate file), and even when I put the definition in the header file of the class using it it gives the warning:
#protocol SubstitutableDetailViewController <NSObject>
- (void)showRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem;
- (void)invalidateRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem;
#end
#interface LauncherViewController :TTViewController<SubstitutableDetailViewController, TTLauncherViewDelegate> {
TTLauncherView *launcherView;
}
So what do I do wrong in my definition of the protocol?
[EDIT: Sorry, there must be an oddity in Xcode, or I am going mad, I did a clean build and now the warning does not come back... but I don't know why]

Put this code in a separate file named SubstitutableDetailViewController.h (I'd prefer SubstitutableDetailViewControllerDelegate.h):
#protocol SubstitutableDetailViewController <NSObject>
- (void)showRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem;
- (void)invalidateRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem;
#end
And then include it in LauncherViewController via #import "SubstitutableDetailViewController.h"

Related

Header/main files in Objective C

I am reading about iOS programming and I bought the Programming iOS 4 book. There is a introductory part where among several things "Files" is mentioned.
I don't understand how the source files is put together. You have a header file with function declarations, then you have a corresponding file with the function definitions.
Let say you have a Car.h and Car.m & Person.h and Person.m.
Now, if you want to use the Car in the Person class you would import only the Car.h file. How is this sufficient? I don't understand the sequence it put together and builds a program. (Not thinking about the technical stuff, just h/m files.)
The .h or "header file" contains the interface.
The .m or "implementation file" contains the implementation.
Each implementation file is also called a "compilation unit" because the compiler compiles each one separately. Within each compilation unit, the compiler needs to know about types and methods. All it needs to know about a class to create the right code is information about the methods it implements.
So let's imagine you have these files:
Car.h
#import <Foundation/Foundation.h>
#interface Car : NSObject
- (void)drive;
#end
Car.m
#import "Car.h"
#implementation Car
- (void)drive {
NSLog(#"I'm driving!");
}
#end
Person.h
#import <Foundation/Foundation.h>
#class Car;
#interface Person : NSObject
#property (nonatomic, strong) Car *car;
- (void)start;
#end
Person.m
#import "Person.h"
#import "Car.h"
#implementation Person
#synthesize car;
- (void)start {
[car drive];
}
#end
Now when the compiler does its business, it compiles both Car.m and Person.m into Car.o and Person.o respectively. [These then get linked into the final binary, but that's beyond the scope of this question for now].
When it compiles Person.m, the compiler doesn't need to know how - (void)drive of Car is implemented, but it does need to know that it exists, that it is a method that takes no arguments and returns nothing. It doesn't care about the implementation, just that it exists. So you just need to #import the header file of Car to tell the compiler about the methods that exist on Car. The compiler knows that the implementation exists, because you've told it so, and then later on the linker will do it's business to correctly wire up the method call to the correct implementation. How the linker actually does that is a huge topic and I encourage you to go and read about it separately if you don't already understand it.
Note that it's the same for all of the standard NS classes that you use such as NSObject, NSString, etc. You just need to #import Foundation.h from the Foundation framework which tells the compiler about what these classes are and what methods are defined on them.
Creating an executable from a set of source code files is a two stage process.
Firstly, all of the .m files are individually compiled with the Objective-C compiler. This turns each one into a .o file which is an object code file. However, if the code in a .m file refers to things that are defined in other .m files, the compiler does not know about these so it just leaves unresolved references in the .o file.
The second stage is called linking. This takes all the .o files and combines them into an executable. When the linker finds unresolved references in one .o file, it checks all the others to resolve the reference.
Header files allow the compiler to have some information from outside the particular .m file it is currently compiling. So if you have two classes Foo and Bar they are conventionally defined in files Foo.m and Bar.m In order for the compiler to know what class Bar looks like when it is compiling Foo.m we put class Bars interface declaration in a header file (conventionally Bar.h) and import it into your .m file. If you see the line
#import "Bar.h"
it is literally as if the compiler has copy-pasted the entire header file into the source code file before compiling it.
What language have you been using until now? Many languages do it this way including c and c++. The m files are compiled into an actual program, and the h files provide a list of ways to interact with it. While you can still call the methods if you interact with the objective c runtime, the compiler will not guarantee their existence unless they are in the h file.
Now, I say guarantee, but if you dont provide an implementation in the m file, the sibling to the compiler, the linker will have a fit. It will try to make a jump into another m file based on its h file only to tragically discover that it is not there.
The benefits of splitting like this is that you can compile your source into a library and distribute it along with the h files and another application can use it without having the implementation source code.
In summary the m files compile into a lost island of bits and the h files are the map to get around it. If something is on the map that doesnt exist then you will get lost. If something exists but is not on the map then you will have a lot of trouble finding it.
Header files specify what messages ("methods" in other languages) can be passed to a class. That's all the compiler needs to know to compile your code; the linker will eventually wire everything up, so to speak, using the *.m files.
The compiler will handle that for you.
As you stated, a header file contains just the declarations.
Its like a interface to the actual code and that is the only thing Compiler needs to know to fetch the rest.

Unknown Expected identifier

I have taken over a project and am fairly new to cocotouch. I was looking throught the code trying to understand things. I didn't think I changed anything but when I went to run It came up with three build errors (it had run just a few minutes before with no problems). The second two seemingly related to the first:
#import <UIKit/UIKit.h>
#protocol MapViewDelegate; //Expected identifier or '(' before 'protocol'
#interface MapView : TTImageView
{
id<MapViewDelegate> mv_delegate; //Cannot find protocol declaration for 'MapViewDelegate'
}
#property (assign) id<MapViewDelegate> mv_delegate; //Cannot find protocol declaration for 'MapViewDelegate'
#end
#protocol MapViewDelegate <NSObject>
- (void)mapView:(MapView *)mv pressedAt:(CGPoint)point;
- (void)mapViewFinishedLoading:(MapView *)mv;
#end
I am using XCode4 which I have just switched to but have had working since the switch.
What is going on here?
MapKit.framework has been added to the project?

The same error i all headers - error: expected '='... before 'protocol'

I've been working on an iOS project for some time but now I have an error which really confuses me and as long as I can't fix it I can't even compile the project so I need some serious help!
It all began with an:
error: expected '=', ',', ';', 'asm' or 'attribute' before 'protocol'
in PHCluesListViewController.h. The class had not been changed for a long time and what I was working on at the moment of the error had nothing to do with that particular class.
This is what it looks like:
#import <UIKit/UIKit.h>
#protocol PHCluesListViewControllerDelegate;
#class PHClueListTableViewController;
#interface PHCluesListViewController : UIViewController {
IBOutlet PHClueListTableViewController *clueListTableViewController;
id <PHCluesListViewControllerDelegate> delegate;
}
- (void)mapDelegate;
#property (nonatomic, assign) id <PHCluesListViewControllerDelegate> delegate;
#end
#protocol PHCluesListViewControllerDelegate
- (void)mapUp:(PHCluesListViewController *)controller;
#end
There are no syntax errors and there is nothing wrong with the code in it's context either. Later I would learn that if you were to take away all the code from the header file the error would move to a another random header file or if you were to import another header the error would move to this header.
I've tried to restart xcode, to move the project to a new one, to rewrite the code to a new file and to move the project to another computer with another version of xcode - but with no luck.
I am able to run other xcode-projects on my computer.
It seems to me that xcode are trying to compile my headers in this specific project in some unwanted fashion.
Help would be highly appreciated, thanks on before hand!
---------- EDIT!!! ----------
Thanks for the fast respond!! Although I've found the answer.
The error was a "d" written out of bounds of the implementation in a totally different file/class. Found it by chance...
If something similar would happen to anyone else; check for something like a letter written after #end or before #interface/#implementation or anything else that would "cut the edges" of the common syntax.
It's difficult to find the reason for an error like this and I'm a little bit surprised that I found it so quickly among 80 files (only 4.5 hours).
Good luck!!
You're defining #protocol PHCluesListViewControllerDelegate twice. Also, if mapUp is required to be implemented, you might want to add the #required keyword.

Objective-C properties are not being recognized in header file?

I wonder if I'm doing something completely stupid here... I'm clearly missing something. I've gotten used to the pattern of defining properties of a custom class, however I seem to be hitting a point where extended classes do not recognize new properties. Case of point, here's my header file:
#import <UIKit/UIKit.h>
#import "MyTableViewController.h"
#interface MyRootController : MyTableViewController {
NSMutableArray *sectionList;
}
#property (nonatomic, retain) NSMutableArray *sectionList;
#end
Now, for some reason that "sectionList" property is not turning green within my interface file (ie: it's not being recognized as custom property it seems). As a result, I'm getting all kinds of errors down in my implementation. The first is right at the top of my implementation where I try to synthesize the property:
#import "MyRootController.h"
#implementation MyRootController
#synthesize sectionList;
That synthesize line throws the error "No declaration of property 'sectionList' found in the interface". So, this is really confusing. I'm clearly doing something wrong, although I can't put my finger on what.
One thought: I am extending another custom class of my own. Do I need to specify some kind of super-class declaration to keep the architecture from getting sealed one level up?
Drat, it was a pathing issue. I still haven't figured out quite how XCode decides what folder to place new files into... and when two joined files end up in different folders, things don't work. Thanks for the reply, fbrereto.

Iphone-sdk - "can not use an object as parameter to a method"

my .h file is as follows
#import <Foundation/Foundation.h>
#interface MyClass : NSObject {
}
- (void) addWidget: (Widget*)aWidget;
#end
For sake of example, Widget is just some simple class that only holds a couple of strings. Apparently, either i'm doing something wrong or am just spoiled by Java / C# because when I try building, the compiler tells me that i can't use an object as a parameter to a method.
Does anyone know what I'm doing wrong? Or do objective-c methods not accept complex types? (say it ain't so!)
[UPDATE]
Ok this is odd.. but I just selected "clean" from the Build menu and now the error went away.. ah.. such misdirection on my part.
The only thing wrong with that code is that Widget isn't declared anywhere. You should either #import "Widget.h" or put #class Widget; before the type is used.