Why can't I use my View Controller as a property? - iphone

for some reason I get an error here
#import "OtherViewController.h"
#interface ViewController: UIViewController
#property (nonatomic, strong) OtherViewController *otherViewController;
this gives me an error saying 'unknown type name OtherViewController' why is this happening to me? Is this not the way to send messages to other view controllers. If so what is the way you are supposed to do this?

From what you have posted, there isn't anything wrong with what you have posted. That being said, you don't need to declare a property for the other VC. What you need to do is declare a public property on OtherViewController (like an NSString) and then you can access that property from the ViewController class. Something like (assuming you are using Storyboards):
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"MySegueID"]) {
OtherViewController *ovc = segue.destinationViewController;
ovc.myPublicNSStringProperty = #"Something";
}
}

Try to import the header in the .m file
#import "OtherViewController.h"
and in the header .h file add
#class OtherViewController;

I can't know for sure since there's not enough info given, but I've seen similar errors if you have circular imports. That is, if OtherViewController.h includes #import ViewController.
So, you could try using #class in one of them to avoid the circular references:
#class OtherViewController;
The, be sure to include in your ViewController.m:
#import "OtherViewController.h"

Related

Trouble with error 'cannot find protocol declaration'

I got SO questions also same as this and I tried with solution but still its not working for mine so asked this again.
This is my VCWithProtocol.h
#protocol mydemoDelegate
#optional
-(void)demoDelegateMethodWithSuccess:(BOOL)yesOrNo;
#end
#interface VCWithProtocol : UIViewController
{
id<mydemoDelegate>mydelegate;
}
#property (nonatomic,assign)id<mydemoDelegate>mydelegate;
VCWithProtocol.m
`#synthesize mydelegate`
This is my class where I am trying to use my Delegate
#class VCWithProtocol;
#interface VCTOUseDelegate : UIViewController <mydemoDelegate> //here is where it shows error with cannot find protocol declaration
VCTOUseDelegate.m
VCWithProtocol *obj = [[VCWithProtocol alloc] init];
obj.mydelegate = self;
I tried with Importing VCWithProtocol but not working as well
Instead of #class VCWithProtocol; write #import VCWithProtocol.h
And some good practice Use capital letter for first character of any class name and protocol.
e.g. MyDemoDelegate and avoid retaining delegate use
#property (nonatomic,assign)id<mydemoDelegate>mydelegate;
Synthesize your mydelegate, and call
[self mydelegate];
You need to add #import "VCWithProtocol.h" to the top of your .m file.
#property (nonatomic,**weak**)id<mydemoDelegate>mydelegate;
delegate always needs weak link

My #property is declared yet I still get may not respond to warning

I don't like warnings lying around and this one has been bothering me. Any ideas on what I am doing wrong? I have tons of properties using this same approach and none of them are giving me warnings. Why doesn't Xcode recognize this one?
While the app works as expected, Xcode gives me the following compile time warning:
'OnlinePeerBrowser' may not respond to '-setMyParent:'
My property declaration in OnlinePeerBrowser.h
#import "WelcomeViewController.h"
#interface OnlinePeerBrowser : UIViewController <UITableViewDelegate, UITableViewDataSource, NSNetServiceBrowserDelegate> {
WelcomeViewController *_myParent;
}
#property (nonatomic, assign) WelcomeViewController *myParent;
OnlinePeerBrowser.m has
#synthesize myParent=_myParent;
I am getting the warning on setMyParent in WelcomeViewController.m here...
#import "WelcomeViewController.h"
#import "OnlinePeerBrowser.h"
#implementation WelcomeViewController
- (void)peerPickerController:(GKPeerPickerController *)picker didSelectConnectionType:(GKPeerPickerConnectionType)type {
...
OnlinePeerBrowser *controller = [[OnlinePeerBrowser alloc]
initWithNibName:#"OnlinePeerBrowser" bundle:nil];
[controller setMyParent:self];
}
Also, what is weird is that I can not use the dot syntax here either.
controller.myParent = self;
gives me the following error:
/Users/vesselhead/Development/iPhone/DJBox/WelcomeViewController.m:254: error: request for member 'myParent' in something not a structure or union
I feel like I must be missing something very simple.
The code you've posted looks correct. That means that the compiler is pulling in another declaration of the OnlinePeerBrowser class from somewhere.
Check for circular imports.
Check if you have multiple copies of the OnlinePeerBrowser.h file.
Add the line #warning Testing to your OnlinePeerBrowser.h file. That warning should then appear in the log when you compile. If that warning doesn't appear then that file isn't being picked up by the compiler.
If it's a circular import then don't import "WelcomeViewController.h" in "OnlinePeerBrowser.h". Instead, use a forward declaration in OnlinePeerBrowser.h, e.g. #class WelcomeViewController , and import "WelcomeViewController.h" in OnlinePeerBrowser.m
Sometimes Circular Imports create an issue with the compiler.
Instead of using
#import "WelcomeViewController.h"
in OnlinePeerBrowser.h move that line to the OnlinePeerBrowser.m and add
#class WelcomeViewController
to the OnlinePeerBrowser.h
this will allow you to set the Class of myParent and _myParent to WelcomeViewController and not have the Circular Import.
Alternatively:
you may want to use a #protocol that the WeclomeViewController would have to adhere to. Then you would only have to import the Classes in one direction.
the implementation for a Protocol property would be as Follows
//#import "WelcomeViewController.h"
#protocol OnlinePeerBrowserParent <NSObject>
#required
- (NSString*) informationFromParent;
#end
#interface OnlinePeerBrowser : UIViewController <UITableViewDelegate, UITableViewDataSource, NSNetServiceBrowserDelegate> {
id<OnlinePeerBrowserParent> _myParent;
}
#property (nonatomic, assign) id<OnlinePeerBrowserParent> myParent;
notice the Protocol is on the OnlinePeerBrowser.h so you can import the OnlinePeerBrowser.h and get the Protocol by default.
finally you implement the Protocol in the WelcomeViewController as so
#implementation WelcomeViewController<OnlinePeerBrowserParent>
- (NSString*) informationFromParent
{
return #"My Parental Info";
}
...... etc

Expected specifier-list before "MainViewController / Method -x not found return type defaults to id

I have the following imports in my EquivalenceClassGroup
#import "MainViewController.h"
but then in my property in EquivalanceClassGroup.h:
#property (nonatomic, assign) MainViewController *myController;
I get this error: "Expected specifier-list before MainViewController when compiling
If I change the import to: #class MainViewController and comment out the import of MainViewController.h that error goes away but then then XCode can't find the methods in my MainViewController from EquivalenceClassGroup.m so from here:
-(id)initWithLetterNumbers: (int)numOfLettersInWord enteredLetter: (NSString *) str controller:(UIViewController *)controller {
myController = (MainViewController *) controller;
letterArray = [myController getLetterArray];
[myController getLetterArray];
I get: "Method -getLetterArray not found return type defaults to id" on that last line
I have this method defined in the MainViewController: -(NSArray*)getLetterArray;
and there are no errors in that interface file or the m file. In the equivalence class if I type in [myController then space, I cant seem to find any methods.
From the MainViewController class I do import the EquivalenceClassGroup and use the methods without any problems
You have to make sure that you import the MainViewController.h file in your .m file. All the #class does is tell the interface that there is such a class, but it doesn't tell it anything about the class. That is what #import essentially does. The #class in the .h file is just good programming practice to make sure that you are doubling importing or anything. Hope that helps!
I think you have to write #import "MainViewController.h" in EquivalanceClassGroup.h file and
#class MainViewController in MainViewController.h file.
#class MainViewController
in your EquivalenceClassGroup.h
#import "MainViewController.h"
in EquivalenceClassGroup.m
This is called "forward declaration" and is quite common.

access a property in UIView in Viewcontroller?

I have been given a project to edit. I think this is a simple question but want to explain it in detail.I usually set up iPhone projects with interface builder and then have a view controller h and m file.
However this has been set up in a different way I am new to, the view has been coded.
The h file is a simple viewcontroller class like this:
#interface MainViewController : UIViewController
{
}
- (id)init;
#end
And then the m file has this:
#interface MainView : UIView
{
NSUinterger firstinterger;
}
- (id)initWithImages:(NSArray *)inImages;
#end
And then it has the #implementation MainView just after that with lots more code.
Further down however is where I need to add my code just after
#end
#implementation MainViewController
But I need to access the NSUinterger named first integer and I am unable to. I have tried a few ways of synthesizing etc. but I think I am doing it wrong. How I would get the value of it? I can access it in the code before the #implementation MainViewController but not after which is where I need it.
Synthesize the variable in MainView. Have an instance of the MainView in MainViewController and then you can access it by
MainView *mv = [[MainView alloc] init];
mv.firstInteger // gives you the variable.
NSUinterger firstinterger in your code shows no ';' at the end of that line, do you get compilation errors or is it just a typo in your question?

How do I resolve this circular dependency?

I'm new to iOS development and am running into an issue with my header files. I'm running into a circular dependency issue with my header files. My application delegate class contains a pointer to my view controller, since I have to set one of the view controller's properties in my didFinishLaunchingWithOptions method...
//appDelegate.h //DISCLAIMER: THIS IS UNTESTED CODE AND WRITTEN ON THE FLY TO ILLUSTRATE MY POINT
#import <UIKit/UIKit.h>
#import "MyViewController.h"
#interface appDelegate
NSManagedObjectContext *managedObjectContext;
MyViewController *viewController;
BOOL myFlag;
#end
//appDelegate.m
#implementation appDelegate
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
viewController.managedObjectContext = self.managedObjectContext;
.
.
.
}
#end
And in my view controller, I reference the "myFlag" property, that's in my app delegate...
//MyViewController.h
#import "appDelegate.h" //<---circular dependency, causing "Expected specifier-qualifier-list before MyViewController" errors in my appDelegate header file
#interface MyViewController: UIViewController
{
NSManagedObjectContext *managedObjectContext;
}
#end
//MyViewController.m
#import "MyViewController.h"
#implementation MyViewController
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
((appDelegate*)[[UIApplication sharedApplication] delegate]).myFlag = NO;
}
#end
But in order to access the "myFlag" property in my app delegate, I need to import the app delegate's header file. This is what's causing the circular dependency. Not sure how to resolve this, has anyone run into this?
Thanks in advance for your help!
Don't #import "MyViewController.h" in appDelegate.h. Instead, forward-declare the class.
#class MyViewController;
#interface appDelegate
NSManagedObjectContext *managedObjectContext;
MyViewController *viewController;
BOOL myFlag;
#end
Also, you don't need to #import "appDelegate.h" in MyViewController.h if all you need is to reference the myFlag property in the implementation. Instead, import it in the MyViewController.m file.
#class is the syntactic approach you're looking for.
Many coders look to avoid this circularity (which couples your classes in two directions, meaning your view controller can only be used in circumstances where the app delegate has that BOOL). There are a few ways you can do this:
Move the state variable to a singleton
Have the view controller fetch the value through an interface that the delegate implements
Key-Value Observing (which your app delegate would configure on your view controller)
For small projects this kind of dependency is probably not really a problem, but as project size grows and the desirability of code reuse grows, clean functional separation becomes more and more valuable.
Did not read everything, but you can do forward declarations with #class. Usually how I solve circular dependencies.