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 (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]

Reply via email to