iPhone - Custom Class Won't Access Method


iPhone - Custom Class Won't Access Method



I'm trying my hand at some iPhone programming and I've run across something that may be fairly obvious to veterans but I'm not exactly sure why it's happening. I have two UIViewController classes, and I want to access a method from the other class. I have two NSObject classes associated with both of them in IB (with the Class file as UpdateClass for each), and I'm trying to create a class and call a method. Seems pretty easy, but the problem is that it's calling the method (according to NSLog) but it's not updating the labels. Here's my code:

//UpdateClass.h #import <Foundation/Foundation.h>  @interface UpdateClass : NSObject {     IBOutlet UILabel *lbl1;     IBOutlet UILabel *lbl2; }  @property (nonatomic, retain) IBOutlet UILabel *lbl1; @property (nonatomic, retain) IBOutlet UILabel *lbl2;  - (void)updateLabels;  @end  //UpdateClass.m  #import "UpdateClass.h"  @implementation UpdateClass  @synthesize lbl1; @synthesize lbl2;   - (void)updateLabels {     NSString *someWord = @"Whatever"; // This could be anything     NSLog(@"NSObject Update");     [lbl1 setText:someWord];     [lbl2 setText:someWord]; }   @end  //ViewController1.h #import <UIKit/UIKit.h> @class UpdateClass; @interface ViewController1 : UIViewController { IBOutlet UIButton *button1; NSObject *UpdateClassObject; UpdateClass *updateClass; } @property (nonatomic, retain) IBOutlet UIButton *button1; @property (nonatomic, retain) NSObject *UpdateClassObject; @property (nonatomic, retain) UpdateClass *updateClass; - (void)updateLabels:(id)sender; @end  //ViewController1.m #import "ViewController1.h" #import "UpdateClass.h"  @implementation ViewController1 @synthesize button1; @synthesize UpdateClassObject; @synthesize updateClass;  - (void)viewDidLoad {     [super viewDidLoad];     updateClass = [[UpdateClass alloc] init]; }  - (void)updateLabels:(id)sender; { //This is connected to TouchDown on button1     NSLog(@"Calls UpdateLabels");     [updateClass updateLabels]; //Calls the class method }  //ViewController2.h #import <UIKit/UIKit.h> @class UpdateClass; @interface ViewController2 : UIViewController { IBOutlet UIButton *button2; NSObject *UpdateClassObject; UpdateClass *updateClass; } @property (nonatomic, retain) IBOutlet UIButton *button2; - (void)updateLabels:(id)sender; @end  //ViewController2.m #import "ViewController2.h" #import "UpdateClass.h"  @implementation ViewController2 @synthesize button2; @synthesize UpdateClassObject; @synthesize updateClass;  - (void)viewDidLoad {     [super viewDidLoad];     updateClass = [[UpdateClass alloc] init]; }  - (void)updateLabels:(id)sender; { //This is connected to TouchDown on button2     NSLog(@"Calls UpdateLabels");     [updateClass updateLabels]; //Calls the class method } 

So there is an NSObject hooked up in IB for both Views. There is a label on each view hooked up to the NSObject and the File's Owner (may not be necessary to hook them up to both). When the button is pressed (which is also hooked up properly in IB), the label is supposed to change to some string. NSLog reports that the methods are called, but the labels don't change. What's wrong here?

(note: there may be some small mistakes as I had to type out some of this because I don't have all the code with me at the moment).




How to cast member variable pointer to generic type in C++

1:



Dynamically Create Subclass
A word on design here:.
Calling methods of “parent” component in Java
You seem to want to share some functionality among two or more view controller implementations.


Domain Entity Property Names
In this case, you may want to create a common base class that derives from UIViewController and derive your two views from that class.


Class vs Struct for data only?
The BaseView would declare the outlets for common UI components which you can connect in IB..
Singleton in PHP
@interface BaseUIViewController : UIViewController {     IBOutlet UILabel *lbl1;     IBOutlet UILabel *lbl2; }  @property (nonatomic, retain) IBOutlet UILabel *lbl1; @property (nonatomic, retain) IBOutlet UILabel *lbl2;  - (void)updateLabels;  @end 
....
Java synchronized static methods: lock on object or class
@interface ViewController1 : BaseUIViewController {     IBOutlet UIButton *button1; 
....
Help needed--Is class necessary in Python scripting?


2:


If the NSLog() runs but the labels don't update, it's almost certainly that lbl1 and lbl2 are nil.

They are almost certainly nil because they're not actually connected in IB, or you're running this code prior to -viewDidLoad running.

In your design here, you must avoid -updateLabels until after the view has actually loaded and wired its outlets.

Views load lazily, so these labels won't be created until right before displaying the view for the first time.. The short version is that you should probably be calling -updateLabels in -viewDidLoad..


3:


OK, there's several aspects of this code that are confusing, so I'll start with the apparent distinction you are making between objects and classes.. What is the purpose of:.
NSObject *UpdateClassObject; 
What is it? How is it assigned (from a nib?)? From the name, it seems you simply want an instance of your UpdateClass class, which is the purpose of:.
UpdateClass *updateClass; 
You don't appear to be using the former so I'm not sure why it's there at all.. Now, on to the crux of your problem: You are calling [updateClass updateLabels] and your NSLog statement indicates that it is indeed being called.

Which tells me that the most likely problem is both instances of your labels lbl1 and lbl2 are in fact nil.

Remember, in Objective-C, sending a message (like updateText: in this case) to nil won't throw any errors, it will just fail silently.. So why are they nil? Well, they are declared as IBOutlets which makes me think you have a NIB file whose file owner is UpdateClass which does the actual wiring of some UILabels to your member variables.

If this is correct, then you need to initialze updateClass with the NIB correctly:.
updateClass = [[UpdateClass alloc] initWithNibName:@"UpdateClass" bundle:nil]; // or whatever the nib is called 
But what you are actually doing is:.
updateClass = [[UpdateClass alloc] init]; 
This means the class is never initialized from a NIB and your labels aren't ever being wired up.. One final point, using the word 'Class' in your class names is fairly redundant - its obviously a class.

This can also lead to confusion - the instance variable you are storing your instance of UpdateClass in is called updateClass - to me, this would mean its actually storing an instance of an object whose type is Class (which you could get by calling [SomeClass class])..


4:


You are sending the updateLabels message to the wrong UpdateClass.. You said you hooked up an instance of UpdateClass in InterfaceBuilder which has the connections to the labels set in IB too.

Thus, when your view is loaded, it has the UpdateClass object injected already from the NIB.. In your viewDidLoad implementation you create a new instance of UpdateClass.

That instance does not have the labels set (they are nil).

Thus, once you send the updateLabels method to that object, that object has no labels to update.. Just throw out the declaration and allocation of updateClass in viewDidLoad and send the updateLabels message to UpdateClassObject.

Consider renaming the member UpdateCLassObject to updateClass or even better, rename the class to something like updater.

Also consider using a base class instead..



76 out of 100 based on 56 user ratings 1306 reviews