Re: NSOperation and lazy loading
Re: NSOperation and lazy loading
- Subject: Re: NSOperation and lazy loading
- From: Roland King <email@hidden>
- Date: Tue, 15 Sep 2009 12:33:54 +0800
Christopher Drum wrote:
A recurring theme in Cocoa development is that of "being lazy" and of
"lazy loading" and the like. Given this Cocoa development pattern, I am
having a difficult time understanding the architecture of the following
scenario.
1. We have a "Person" object which will fetch an image of said Person
from the internet in a lazy fashion; i.e. we only load it if it is
explicitly asked for.
2. The operation the Person object uses to load its own UIImage lazily
is run on a background thread via a subclassed NSOperation class. In
this PersonImageOperation class, the main() method returns the fetched
UIImage to the main thread via
"performSelectorOnMainThread:withObject:waitUntilDone:"
3. Some object initializes a Person object, which we'll call
"christopher" and requests its image thusly:
Person *christopher = [[Person alloc] initWithFacebookID:@"bogusid"];
UIImage *currentImage = [christopher image];
4. "christopher" currently has no image to return, so it puts
PersonImageOperation on the queue with a URL of an image.
PersonImageOperation does it's magic and returns is thusly:
[target (in this case, christopher)
performSelectorOnMainThread:@selector(didFinishLoadingPersonImage:)
withObject:fetchedImage waitUntilDone:NO];
5. "christopher" now has its image, but the original requester asked
for in the (UIImage *)image method, which necessarily returned NIL at
the time because the image hadn't yet been loaded from the internet.
i.e. - "christopher" SHOULD have returned an image, but DIDN'T; however
it will EVENTUALLY .
So what is the recommended architecture for the original requester to
remain interested in receiving the image when it finally finishes
loading? I believe I need the requesting object to register for a
notification of some sort, which means that in order to receive the
image from a Person object, the requesting object must handle both
cases: the image is immediately available (because the Person object
cached it) or the image is currently nil but will be ready later. If
that's the case, then why would I ever do anything BUT listen for
notifications? On the other hand, that seems like a strange
architecture when all I want to do is ask an object for some piece of
data, which may be cached and ready to go the next time its requested!
Am I just thinking myself into circles here? Am I perhaps (and this is
very likely) making this harder than it needs to be? NSOperation seems
to be very easy to use when the object that needs some work done spins
off its own NSOperation to do that work, but when there an extra layer
of abstraction the process gets confusing quickly.
I hope I've explained my muddled thinking clearly enough to get a kick
in the right direction, and thanks in advance for help and
clarification on the matter.
Christopher Drum
http://software.christopherdrum.com/
Seems like a job for KVO (Key Value Observing). with some mail-typed code
NSImage christophersImage = [ christopher image ];
if( !christophersImage )
{
[ self displayImage:<some kind of transient loading image> ]
[ christopher addObserver:self forKeyPath:@"image" .... ];
}
else
{
[ self displayImage:christophers Image ];
}
Then in your KVO method
-(void)observeValueForKeyPath:.. ofObject:.. change:.. context:..
{
// check context, check path, now you know the image is valid
[ self displayImage:[ object image ] ];
// and stop listening
[ object removeObserver:self forKeyPath:keyPath ];
}
just make sure image is a KVO compliant property and you're good to go.
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden