Reputation: 888
I have a NSObject
class with NSStrings
and UIImages
. I fill them by downloading data from a server. What I do in a manager class, I download a JSON and parse it into the NSObject
to fill the basic NSString
& UIImages
. Then I launch a method in the NSObject
's class to download the more complex data from another server and put the NSObject
into a NSMutableDictionary
. So what I end up with is a dictionary full of my NSObjects
, with some data already downloaded and some data still downloading.
Then I try to feed the data of the NSObject
into UILabels
, and UIImageViews
in another class (view controller). However, some of the data will probably still be loading so their so the UILabels would show up empty if for example the NSString
that should fill it wouldn't be downloaded yet.
Now my question is, how can I change the UILabels
's text again, once the NSString
in it's NSObject
class has been downloaded (re-set)? Basically I'd need to "observe" the NSObject
's NSString
's value from the UILabel
's class. I've found something like this:
observeValueForKeyPath:ofObject:change:context
But I have no idea how to use it. I know I'd have to implement it in the UILabel
's class, but how, and how do I set it to update the UILabel
's text when it observes a change in the NSObject
's NSString
?
Also I've read something about a NSObjectController
class, is it applicable here?
Thank you in advance!
Upvotes: 1
Views: 610
Reputation: 5519
Basically you need to implement the following in your UILabel
subclass:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:@"nameOfThePropertyInYourNSObjectSubclass"]) {
id changedValue = [object valueForKeyPath:keyPath];
//do what ever you want with it
}
}
Also to register your NSObject
subclass for KVO, you need to implement:
[self addObserver:yourUILabel forKeyPath:@"nameOfThePropertyOfYourString" options:NSKeyValueObservingOptionNew context:NULL];
Note that you also have to unregister the observer at the appropriate time (depending on your design):
[self removeObserver:yourUILabel forKeyPath:@"nameOfThePropertyOfYourString" context:NULL];
Also note, that, while KVO is a neat thing and quite useful in some cases, it's be no means a no brainer to choose it. Especially in your case I would recommend to use a callback instead. Fetching data from the network is best done in a background thread, in that case I would use a delegate pattern to inform your view controller, that new data is available and let the view controller take care of updating your labels.
Upvotes: 1
Reputation: 130092
KVO is possible, but also check out delegate pattern. I believe it would be simpler here.
Upvotes: 0
Reputation: 60110
You're very close - what you want is called key-value observing, and it's described in detail in the Key-Value Observing Programming Guide. You don't need an NSObjectController for this - instead, have the view controller managing the view for the UILabels add itself as an observer for the other class, then just update the UILabel text whenever you receive the observeValueForKeyPath:ofObject:change:context
message.
Upvotes: 1