Re: Working with Notifications and NSFileHandle
Re: Working with Notifications and NSFileHandle
- Subject: Re: Working with Notifications and NSFileHandle
- From: Ken Thomases <email@hidden>
- Date: Fri, 27 Jun 2008 19:11:54 -0500
On Jun 27, 2008, at 3:32 PM, Wan, Nathan (CIV) wrote:
I'm new to Objective-C and Cocoa and I am having trouble with the
notifications system. This I thought was just a small project to
write a native mac program to continuously read and write data from
a serial port to a file. It was suggested I use NSFileHandle to
maintain safe threads, as it can read the serial port
asynchronously; I had hoped this program would read the text file,
and as I changed it, there would be an output to the console.
Something simple to see the notification system in action:
//CODE
#import <Cocoa/Cocoa.h>
#import <Foundation/NSFileHandle.h>
#import <Foundation/NSString.h>
#import <Foundation/NSNotificationCenter.h>
Once you've imported Cocoa.h, I don't think you need to explicitly
import these Foundation headers.
#import <stdio.h>
If you were to use NSLog rather than printf, you wouldn't need this
either.
@interface test : NSObject
-(void) writeDataReadInBackground:(NSNotification *)notification;
-(void) testWriteData:(NSData *)data;
@end
int main(int argc, char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSData *aData = [@"Test" dataUsingEncoding:
NSASCIIStringEncoding];
NSFileHandle *in = [NSFileHandle fileHandleForReadingAtPath:@"/
Users/_me_/test.txt"];
if(in == nil)
printf("somethig wrong\n");
test *t = [[test alloc] init];
[[NSNotificationCenter defaultCenter] addObserver: t
selector:@selector(writeDataReadInBackground:) name:
NSFileHandleDataAvailableNotification object: nil];
In this simple test case, passing nil for the object to observe is
fine. In general, though, you'd get the
NSFileHandleDataAvailableNotification notification from all file
handles in the app, which is sure to confuse your code.
[t testWriteData: aData];
[in waitForDataInBackgroundAndNotify];
while(1)
sleep(5);
This is the crux of your problem. Nothing can happen in this main
thread during this loop. In particular, notifications can't be
delivered.
You want to use NSRunLoop:
[[NSRunLoop currentRunLoop] run];
Read the "Run Loops" guide for more information: <http://
developer.apple.com/documentation/CoreFoundation/Conceptual/
CFRunLoops/>.
[t release];
[pool release];
return 0;
}
@implementation test
- (void) writeDataReadInBackground:(NSNotification *)notification {
printf("Notification recieved\n");
You would actually need to read the data here: [[notification object]
availableData]
If you want to keep reading data, you need to reissue -
waitForDataInBackgroundAndNotify. If you do that but don't read the
data, you'll get a constant stream of notifications.
That said, if you are really trying to read data, don't use -
waitForDataInBackgroundAndNotify. Use -readInBackgroundAndNotify and
NSFileHandleReadCompletionNotification instead, both here in the
notification handler and above where the reading is initiated. In
that case, you don't need to call -availableData -- the data is
provided to you in the notification.
}
- (void) testWriteData:(NSData *)data {
NSFileHandle *stdOut = [NSFileHandle
fileHandleWithStandardOutput];
[stdOut writeData:data];
I have no idea what this is about or for. I'm guessing it's just you
experimenting.
}
@end
//END_CODE
Thanks for your help
Nathan
PS What's the proper way to work between NSString and NSData?
What you did above with -[NSString dataUsingEncoding:] is fine. In
the other direction, you can use [[NSString alloc]
initWithData:someData encoding:someEncoding].
Cheers,
Ken
_______________________________________________
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