Re: NSNotifications inside NSThreads?
Re: NSNotifications inside NSThreads?
- Subject: Re: NSNotifications inside NSThreads?
- From: email@hidden
- Date: Wed, 27 Mar 2002 13:20:18 -0800
Appkit is not thread safe.
You can't call into appkit code from anything but the main thread.
use an NSPort to send a message (NSPortMessage ) back from your network
reader thread.
something like this:
@interface MyNetworkReader
{
NSPort *mPort;
}
@end
@implementation MyNetworkReader
- (void)dealloc
{
[[NSRunLoop currentRunLoop] removePort:mPort
forMode:NSDefaultRunLoopMode];
[mPort setDelegate:nil];
[mPort release];
}
- (id)init
{
if (self = [super init]) {
mPort = [[NSPort port] retain];
[mPort setDelegate:self];
[[NSRunLoop currentRunLoop] addPort:mPort
forMode:NSDefaultRunLoopMode];
[NSThread detachNewThreadSelector:@selector(handleConnection)
toTarget:self withObject:nil];
}
return self;
}
- (void)handleConnection
{
while (/*read the data here...*/) {
// make an NSPortMessage, serialize some data into it, and call
sendBeforeDate on it.
}
}
- (void)handlePortMessage:(NSPortMessage *)portMessage
{
// the port message sent above will show up here, but in the main
thread.
// so you deserialize the contents of the message and post your
notification here.
}
@end
On Tuesday, March 26, 2002, at 08:20 PM, Doug Brown wrote:
Hello,
I've been working on the backend of a Cocoa IRC client for a while now,
along with someone else. I don't know much about the BSD socket calls,
but I'm wrapping those calls in NSThreads. (The other guy I am working
with used a pthread, which caused even greater problems than what I'm
experiencing)
Here's the problem - inside the thread, I post a notification when new
data arrives, so I guess the class is operating somewhat like
NSFileHandle. The app then takes this data and puts it in an
NSTextView. We haven't gotten to the parsing of IRC messages yet, we're
just getting the socket class working. At seemingly random times, I'm
getting this error, and at the same time, I get the spinning beachball
of death:
Exception raised during posting of notification. Ignored.
exception: *** -[NSCFArray objectAtIndex:]: index (0) beyond bounds (0)
I'm guessing it has something to do with the notification posting I'm
doing in my thread, but I could be wrong (if i'm wrong, then the title
of this post is misleading). By the way, the notification includes 1
item in the userInfo dictionary: the data received. I'm certain that
this data is not null.
It happens more often if I do a lot of clicking inside a text field in
the user interface, but I'm suspecting it's a more low level problem. I
think it's getting stuck at a lock somewhere, due to the first few
lines that appear in a backtrace using GDB:
(gdb) #0 0x7003f4c8 in semaphore_wait_signal_trap ()
#1 0x7003f2c8 in _pthread_cond_wait ()
#2 0x70816bc4 in -[NSRecursiveLock lock] ()
#3 0x70be12a0 in _NSFastFillAllGlyphHolesUpToGlyphIndex ()
#4 0x70b9f340 in -[NSLayoutManager
notShownAttributeForGlyphAtIndex:] ()
#5 0x70e44808 in -[NSLayoutManager(NSPrivate)
_drawGlyphsForGlyphRange:atPoint:parameters:] ()
#6 0x70bbcea8 in -[NSLayoutManager(NSTextViewSupport)
drawGlyphsForGlyphRange:atPoint:] ()
#7 0x70e59820 in -[NSTextView drawRect:] ()
I'm wondering if I need to execute the code that receives the
notification in a different thread or something. Here's the code
snippet in question, with all the irrelevant parts snipped:
-- in the selector being run in the NSThread:
ap = [[NSAutoreleasePool alloc] init];
while (connected)
{
get data, put into NSString variable
[self postNotification:data];
}
[ap release];
The method that posts the notification:
- (void)postNotification:(NSString *)message
{
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
//the notification center
NSDictionary *ui = [NSDictionary dictionaryWithObject:message
forKey:@"ITIRCData"]; //create userInfo dict with data
NSNotification *n = [NSNotification
notificationWithName:@"ITIRCRawNotification" object:self userInfo:ui];
//create note
[nc postNotification:n]; //post it!
}
Then, an object in another class receives the notification and simply
appends it to an NSTextView and scrolls to the end:
NSString *temp = [NSString stringWithFormat:@"%@\n%@", [textView
string], string];
NSRange theRange;
[textView setString:temp];
theRange.location = [[textView string] length] - 1;
theRange.length = 0;
[serverTextView scrollRangeToVisible:theRange];
Whew. That was a lot - sorry about posting this really big, but I'm
getting desperate for solutions :) Is it because I'm posting the
notification in the receive data thread? Anyone have any ideas on how
to fix this? If you need more code snippets I can send them.
Thanks much,
Doug
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.