Objective C variable accessible by multiple methods
This is my second day programming in ObjectiveC so I apologize for the noob question.
I have a ViewController that does an API call using asy开发者_如何学Gonc and asihttprequest:
@synthesize loadingStatus;
- (void)loadStatsData
{
[indicator setHidden:NO];
loadingStatus = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"bad", nil] forKeys:[NSArray arrayWithObjects:@"amount", nil ] ];
[RESTApiController request:@"/method.json" method:@"GET" options:[NSDictionary dictionaryWithObjects:[NSArray arrayWithObject:@"amount"] forKeys:[NSArray arrayWithObject:@"receiving"] ] parent:self];
}
and receiving it like this:
- (void)requestFinished:(ASIHTTPRequest *)request
{
if (receiving == @"amount")
{
// do stuff
[loadingStatus setValue:@"good" forKey:@"amount"];
}
if ([loadingStatus valueForKey:@"amount"] == @"good"])
[indicator setHidden:YES];
}
The app crashes when it tries to use the loadingStatus variable in requestFinished(). I guess somehow the variable gets dellocated, but I'm unsure as how to approach this.
Two questions: 1) How can I keep loadingStatus's state across methods calls so I can use it in the way I wrote the code 2) Is there a better way of achieving my goal of checking if API calls are completed and hiding the ActivityIndicator?
-M.
Do it this way: refer to loadingStatus as self.loadingStatus
self.loadingStatus = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"bad", nil] forKeys:[NSArray arrayWithObjects:@"amount", nil ] ];
That way, it goes through the accessor, and does a retain on it (the @property part in .h file).
Also, programming hint: break your lines into smaller statements so they are easier to debug.
You are right, loadingStatus is being deallocated. That is because the value is being autoreleased.
If you change
loadingStatus = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"bad", nil] forKeys:[NSArray arrayWithObjects:@"amount", nil ] ];
to
loadingStatus = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"bad", nil] forKeys:[NSArray arrayWithObjects:@"amount", nil ] ];
[loadingStatus retain];
or
loadingStatus = [[NSDictionary alloc] initWithObjects:[NSArray arrayWithObjects:@"bad", nil] forKeys:[NSArray arrayWithObjects:@"amount", nil ] ];
then your code will work.
The reason for this is that the object that is returned from dictionaryWithObjects:forKeys has had autorelease called on it, so if you want to keep it from being deallocated, you need to call retain.
As a reference, if you call alloc/init, you get an object with a retain count of 1. If you use a method such as dictionaryWithObjects:forKeys: you get an object with a retain count of 0. To fix that problem, just add a retain and you will be good to go.
Apple has some really nice documentation on memory management. I recommend checking it out when you have the chance
Memory Management Guide
Memory Management Rules
Hope this helps!
-Scott
精彩评论