Why am I getting an error for this? - objective-c

Why am I getting these errors?
alt text http://img39.imageshack.us/img39/2203/help.tif
It says:
Error: Request for member "jokeTableView" in something not a struction or union
What does that mean? And why is it breaking. I tried reading about initWithStyle but I just could catch up on it
Here is my .h file:
#import <UIKit/UIKit.h>
#interface TableViewController : UITableViewController {
NSMutableArray *jokes;
IBOutlet UITableView *jokeTableView;
}
#property (nonatomic, retain) NSMutableArray *jokes;
#end
Thanks!

Your object (TableViewController) has no property named jokeTableView.
In order to access jokeTableView with the special dot operator, it needs to be a property. Otherwise you have to access it using Key-Value-Coding compliant methods or directly using the -> operator (or just use it as an ivar and no reference to self):
jokeTableView.delegate = self;
or
self->jokeTableView.delegate = self;
or
[self jokeTableView].delegate = self;
or
#property (retain) UITableView *jokeTableView;
// later...
self.jokeTableView.delegate = self;
Also note, however, that you are setting an outlet in the initializer and this won't work. You'll have to set this in the -[TableViewController awakeFromNib] method since self->jokeTableView will be nil when the initializer is actually called (which happens in IB prior to serializing the object into the nib file).

Since you are doing this at init time, the outlets should be NULL, so this initialization shouldn't do anything. This should be done at awakeFromNib time at the earliest.

Related

Objective-C - Call a method that modify a textField from another class

I have two questions :
When I try to call a method from different class (this method modify a textfield after having checked a condition) the method is well called (the NSLog in statutInternet works) but the TextField isn't modified..
When I do it from the (IBAction)internet method it works .. Any solution ?
Why Xcode want me to called my variables (like internetTextfield) with a _ before it ?
WindowsController.h
#import <Cocoa/Cocoa.h>
#interface WindowController : NSWindowController
#property (assign) IBOutlet NSTextField *internetLabel;
- (void)statutInternet;
- (IBAction)internet:(id)sender;
#end
WindowsController.m :
#import "WindowController.h"
#implementation WindowController
- (IBAction)internet:(id)sender;
{
[self statutInternet];
}
- (void)statutInternet;
{
NSLog(#"Callfunctionworks");
if (condition) {
[_internetLabel setStringValue:#"TxtFieldWorks!"];
}
}
I try to call the method statutInternet with this from another class :
WindowController *fenetre = [[WindowController alloc] init];
[fenetre statutInternet];
When I try to call a method from different class it doesn't work:
That's because, You're making another WindowController instance using this code:
WindowController *fenetre = [[WindowController alloc] init];
This is another new separate instance of same class, which I guess you're not showing. So you want to take reference to the window that's already showing rather than making a new instance.
Why Xcode want me to called my variables (like internetTextfield) with a _ before it ?
That's because when you declare variable using #property it does three things:
Makes an internal variable by adding the conventional underscore (_) to the start of the variable name. That's why you've _ as prefix of your variable.
Makes a setter-getter methods.
Takes the keywords you used (ie. assign, strong, weak) in account while implementing the setter-getters.
You can read a good discussion here: #property and retain, assign, copy, nonatomic in Objective-C
The NSTextField (and all of the other UI items) is not created yet when you call statutInternet method.
When your window loaded, your views will be ready :
_fenetre = [[WindowController alloc] initWithWindowNibName:#"WindowController"];
[_fenetre showWindow:_fenetre.window];
[_fenetre statutInternet];

Interface variable declaration: synthesizing and unknown selector

I'm having a confusing problem. I'm only ankle deep in Objective-C so I'll try my best to explain. I have a class, which is a controller that simply declares an NSTextField which is in a nib file.
Here's its declaration in the interface file:
#property (nonatomic, retain) IBOutlet NSTextField *textField;
and in the implementation:
#synthesize textField;
Simple right? But if I call [textField stringValue] on it later on by means of clicking on a submit button then it fails with an unknown selector message (typical if it thinks it can't call that message on that object type). This looked like this:
-(IBAction)send:(id)sender {
NSString* txt = [textField stringValue];
[server send:txt];
}
To fix this, I did the following:
#interface MyController : NSObject {
NSTextField *textField;
}
I've not seen any tutorial/example showing this. They do it without declaring the NSTextField in this section of the interface.
My question is, why in my case do I have to declare it in the interface for it to work?

textView not getting set from another view controller (using Singleton class)

I have a textViewController class. I want to set(basically update) the corresponding textView's content from another view controller which I am pushing over the present textViewController. The way I thought I could do this was to have a shared singleton class and have a string property there to contain the text. I have been using the singleton for storing some other content as well and it worked fine till now.
But the text variable in singleton class doesn't hold the content I pass to it from the second view controller and hence the textViewController, after popping the second view controller, displays the old text even after reappearing. I am updating the textView in its viewWillAppear method which is getting called but shows old text content on NSLogging.
What am I missing here? Please suggest a solution, stuck at it for a long time now.
Declaration
Firstly, declare the NSString in your app delegate .h file. It should look something like this:
//YourAppDelegate.h
#import <UIKit/UIKit.h>
#interface YourAppDelegate : NSObject < UIApplicationDelegate >
{
NSString *sharedString; //WE ADDED THIS
}
#property (nonatomic, retain) NSString *sharedString; //AND THIS
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet SomeViewController *viewController;
#end
Now you want to synthesize the object so that the accessor and mutator methods are made for you. This means you don't have to write the setSharedString: and getSharedString methods - we can simply access and mutate the object by making a reference to it. This is how we synthesize it in the .m file:
//YourAppDelegate.m
#synthesize sharedString;
Assigning a Value
When you want to assign a value to sharedString from another class, you must first retrieve the active instance of your application delegate:
YourAppDelegate *appDelegate = (YourAppDelegate*)[[UIApplication sharedApplication] delegate];
The appDelegate object here is your running app delegate instance. To access the sharedString NSString object in the delegate and assign a value, we'd do this:
appDelegate.sharedString = #"some string we want to assign";
For the duration of our application's runtime, "some string we want to assign" is now stored in sharedString in our app delegate.
Retrieving the Value
You'll want to retrieve the value at some point. To do this, again we'll have to get the running instance of our application delegate:
YourAppDelegate *appDelegate = (YourAppDelegate*)[[UIApplication sharedApplication] delegate];
Once we have the running instance, we can then access the sharedString object stored inside it:
NSString *retrievedString = appDelegate.sharedString;
From this point, retrievedString now holds the value "some string we want to assign".
Note:
Everywhere I mention YourAppDelegate, I am referring to your app delegate - the app delegate you have in your project. It'll be related to your project name (look for the file).
How your NSString property for your Text-Variable is defined? Is it a "weak"?

Can't get custom #protocol working on iOS

Note: the below is using iOS with Automatic Reference Counting (ARC) enabled. I think ARC may have a lot to do with why it isn't working as this is set up as per examples i've found via google.
I am trying to create a protocol to notify a delegate of the filename the user selects from a UITableView.
FileListViewController.h
#protocol FileListDelegate <NSObject>
- (void)didSelectFileName:(NSString *)fileName;
#end
#interface FileListViewController : UITableViewController
{
#private
NSArray *fileList;
id <FileListDelegate> delegate;
}
#property (nonatomic, retain) NSArray *fileList;
#property (nonatomic, assign) id <FileListDelegate> delegate;
#end
FileListViewController.m
#import "FileListViewController.h"
#implementation FileListViewController
#synthesize fileList;
#synthesize delegate;
This gives an error at the
#synthesize delegate;
line which is "FileListViewController.m: error: Automatic Reference Counting Issue: Existing ivar 'delegate' for unsafe_unretained property 'delegate' must be __unsafe_unretained"
If i change FileListViewController.h putting __weak and (weak) then it will run.
#protocol FileListDelegate <NSObject>
- (void)didSelectFileName:(NSString *)fileName;
#end
#interface FileListViewController : UITableViewController
{
#private
NSArray *fileList;
__weak id <FileListDelegate> delegate;
}
#property (nonatomic, retain) NSArray *fileList;
#property (weak) id <FileListDelegate> delegate;
#end
But when I try to set the delegate the app crashes. A view called 'ImportViewController' is creating a view from 'FileListViewController' and setting the delegate to itself (ImportViewController) so I can implement my custom protocol of 'didSelectFileName'. The error I get is;
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[ImportViewController setDelegate:]: unrecognized selector sent to instance 0x6c7d430'
The code I am running is;
ImportViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
FileListViewController *fileListViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"filelist"];
[fileListViewController setDelegate:self];
[self.navigationController pushViewController:fileListViewController animated:YES];
}
My Questions are:
Why does putting (weak) and __weak in make it work? I don't
understand why this works as I found it googling and there wasn't an
explanation.
Why can't I set my delegate using this
'[fileListViewController setDelegate:self];' ? It seems like the
compiler doesn't know 'delegate' exists.
Under ARC ivars default to strong. So the error
Automatic Reference Counting Issue: Existing ivar 'delegate' for unsafe_unretained property 'delegate' must be __unsafe_unretained"
is telling you that you've declared a property with __unsafe_unretained (assign) ownership, where the underlying ivar has __strong ownership, which is illegal. To avoid the error, you have 3 options:
Omit the ivar. It's not necessary to declare an ivar for a synthesized property. The ivar will be declared implicitly with ownership matching your property.
Define the ivar to match your (assign) property declaration: __unsafe_unretained id <FileListDelegate> delegate;
Define the property to match the ivar's implicit __strong ownership: #property (weak) id <FileListDelegate> delegate;
Personally, I'd omit the ivar declaration so you have the ownership semantics in one place, on the property declaration.
It seems that with :
FileListViewController *fileListViewController =
[self.storyboard instantiateViewControllerWithIdentifier:#"filelist"];
you didn't get an FileListViewController object. Look at the message it says :
-[ImportViewController setDelegate:]: unrecognized selector sent to instance 0x6c7d430
and that why your app crashes. Also try to define a retain property, instead of just assign, in case the delegate is deallocated elsewhere, your app won't crash.
I just ran across this same issue, forcing me to finally delve into the ARC documentation.
Also try to define a retain property, instead of just assign, in case the delegate is deallocated elsewhere, your app won't crash.
To maybe clarify the above quote from user756245 's answer, based on my reading I don't think that iOS 5 has changed the best practice that you shouldn't be retaining your delegate as this is a good way to leak. I think the __weak and (weak) tokens are annotations for the compiler for the sake of being able to correctly deal with generating code for the delegate.

Debug / Release build differences for superclass / subclass

I have an iOS project which builds and executes as expected under debug yet throws a compilation error when being built for release. The error is to do with an iVar which is declared in a superclass and it is specifically
'fetchedResultsController_' undeclared (First use in this function).
Here is the superclass .h.
#interface Super : UIViewController <NSFetchedResultsControllerDelegate> {
NSFetchedResultsController* fetchedResultsController_;
NSManagedObjectContext* managedObjectContext_;
}
#property (nonatomic, retain) NSFetchedResultsController* fetchedResultsController;
#property (nonatomic, retain) NSManagedObjectContext* managedObjectContext;
#end
and the superclass .m
#implementation Super
#synthesize fetchedResultsController = fetchedResultsController_;
#synthesize managedObjectContext = managedObjectContext_;
#pragma mark -
#pragma mark Properties
-(NSFetchedResultsController*)fetchedResultsController {
return nil;
}
The Subclass interface is defined thus:-
#interface Sub : Super <UIActionSheetDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate> {
// extra stuff
}
In the subclass .m I implement lazy loading for fetchedResultsController
-(NSFetchedResultsController*)fetchedResultsController {
if (fetchedResultsController_ == nil) { // undeclared error here....
//stuff
}
return fetchedResultsController_;
I'm confused mainly because I don't understand why this would comile in Debug but not in Release!
If someone could identify what the issue is I'd appreciate it greatly
This isn't the answer to your question, but it will make the problem go away.
As things stand, in your Super class, having the instance variable at all is pointless. And you should probably set the property readOnly so people using it know that setting the fetchedResultController property is not allowed. As things stand, people have a reasonable expectation that if they set the property, they'll get more something back when they read it.
So, move the instance variable into the subclass. Declare the property readOnly in the superclass and redeclare it readWrite in the subclass.