properties, threads, and KVO
properties, threads, and KVO
- Subject: properties, threads, and KVO
- From: "Karan, Cem (Civ, ARL/CISD)" <email@hidden>
- Date: Tue, 4 Nov 2008 10:20:13 -0500
- Thread-topic: properties, threads, and KVO
I'm running into a problem with my code that is most easily solved by splitting up everything into a client server model, where the client is the main thread of my application, and the server is a background thread that does networking type stuff. I want the client to update itself as soon as there are any changes in the server. I have two options; I can fix the server to call methods in the client when there are updates, and vice-versa, or I can use KVO and have the client observe changes in the server. The former is fast and easy, but it means that I can only have one client and one server, which is too brittle for what is happening. KVO is ideal, but I don't know it works across threads. My current plan of action is something akin to the following (I banged all of this out in outlook, so there may be syntax errors, but I hope this gets the gist across):
--- Server.h ---
@interface server : NSObject
{
NSImage *periodicallyChangingImage;
NSThread *updaterThread;
id <sourceProtocol> imageSource;
}
@property(retain, readonly) NSImage *periodicallyChangingImage;
- (id) initWithSource:(id <sourceProtocol>) source;
@end
--- End of Server.h ---
--- Server.m ---
@interface server()
@property(retain, readwrite) NSImage *periodicallyChangingImage;
@property(retain, readwrite) NSThread *updaterThread;
@property(retain, readwrite) id <sourceProtocol>) imageSource;
- (void) threadSelector:(id)object;
@end
@implementation
@synthesize periodicallyChangingImage;
@synthesize updaterThread;
@synthesize imageSource;
- (id) initWithSource:(id <sourceProtocol>) source
{
self = [super init];
if (self)
{
self.imageSource = source;
self.updaterThread = [NSThread initWithTarget:self selector:@selector(threadSelector:) object:self];
[self.updaterThread start];
}
return self;
}
- (void) threadSelector:(id)object
{
server *theServer = (server *) object;
NSImage *temp;
while ([self.updaterThread isCancelled] == NO)
{
temp = [self.imageSource getImageBlob]; // This line blocks for a long time sometimes
// I'm hoping that the compiler is smart about locking & unlocking, but splitting the lines should
// take care of any long hangs (the line above hangs, but the line below is fast)
theServer.periodicallyChangingImage = temp;
}
}
@end
--- End of Server.m ---
--- Client.h ---
@interface client : NSObject
{
server *imageServer;
}
- (id) initWithServer:(server *) newServer;
@end
--- End of Client.h ---
--- Client.m ---
@interface client()
@property(retain, readwrite) server *imageServer;
@end
@implementation
@synthesize imageServer;
- (id) initWithServer:(server *) newServer
{
self = [super init];
if (self)
{
self.imageServer = newServer;
[self observeValueForKeyPath:@"periodicallyChangingImage"
ofObject:newServer
change:NSKeyValueObservingOptionsNew
context:NULL];
}
return self;
}
- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
switch (object)
{
case self.imageServer:
if ([keyPath isEqual:@"periodicallyChangingImage"])
{
// Do something with server.periodicallyChangingImage, probably display it immediately.
}
break;
default:
// No idea what the object is, do something intelligent to report the error
break;
}
}
@end
--- End of Client.m ---
I know that properties are supposed to default to thread-safe, and I know that as long as I don’t explicitly specify getter/setter methods, properties should be KVC/KVO compliant, but I'm not sure if the above is 100% kosher. Is there anything I should be worried about?
Thanks,
Cem Karan
_______________________________________________
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