How to update a variable in one class from another?
I need to set a variable in Class A from Class B. To test this, I have a while loop running in Class A that continuously prints the variable via NSLog. However, no matter what I try, I cannot get Class B to update the variable in Class A in such a way that Class A can read the changes made by Class B. I am pretty sure I have everything hooked up properly in IB. Here's how I have things set up:
//Class A
@interface AppDelegate : NSObject {
NSString *teststring;
}
@property(readwrite,nonatomic,retain) NSString *teststring;
@end
@implementation AppDelegate
@synthesize teststring;
-(id)init{
self = [super init];
if(self) {
teststring = [[NSString alloc] init];
}
return self;
}
-(void)awa开发者_JAVA技巧keFromNib
{
while(1){
NSLog(@"teststring is %@",teststring);
usleep(500000);
}
}
@end
//Class B
@class AppDelegate;
@interface otherClass : NSObject {
AppDelegate *appdel;
}
-(IBAction)doTest:(id)sender;
@end
@implementation otherClass
-(void)awakeFromNib
{
appdel = [[AppDelegate alloc] init];
}
-(void)doTest:(id)sender
{
appdel.teststring = @"Test";
NSLog(@"Set teststring to %@",appdel.teststring); //this works
}
@end
You are thinking too much about classes (as seemingly some sort of “department” of code) and not enough about objects, and both your wording and your problem demonstrate this.
You have your instance of otherClass
creating a second instance of the AppDelegate
class. You already had one AppDelegate
instance, which is the actual application delegate (because, I assume, you have it in your nib and you have it hooked up to the application's delegate
outlet there); now, in -[otherClass awakeFromNib]
, you are creating another.
You then tell this second AppDelegate
instance to set its teststring
property to @"Test"
, and then you ask your second AppDelegate
instance for the value of that property, and your second AppDelegate
instance dutifully shows you the value you gave it.
The first instance doesn't have the same value for its teststring
property because the otherClass
object never gave that instance a value for its teststring
property. Note that the variables you define in the @interface
section are instance variables, which is why different instances of a class can and usually will have different values in those variables. Properties are likewise per-instance, being usually backed by these instance variables.
AppDelegate
A (the real application delegate, created in the nib) and AppDelegate
B (created by the otherClass
object, not anything's delegate) are two separate instances of AppDelegate
, with separate teststring
variables.
Thus, the solution: Have the otherClass
instance talk to the real application delegate, not an AppDelegate
instance that it created itself. You could ask the application for its delegate, or (if the otherClass
object is in the MainMenu nib) give it an outlet to the application delegate, just like the application has.
However, piling too much stuff into your application delegate class is bad design; each class should have one specific purpose, and generally should fit neatly within one of the Model, View, and Controller classifications. So, assuming your otherClass
object should be a controller, move the property into otherClass
and make that object the controller of whatever needs the property.
精彩评论