开发者

Can't access UI from a delegate?

开发者 https://www.devze.com 2023-01-01 21:54 出处:网络
I got this code: GrooveOnDownload *dlg = [[GrooveOnDownload alloc] init]; NSURLDownload *dw = [[NSURLDownload alloc] initWithRequest:request delegate:dlg];

I got this code:

GrooveOnDownload *dlg = [[GrooveOnDownload alloc] init];

NSURLDownload *dw = [[NSURLDownload alloc] initWithRequest:request delegate:dlg];

It starts the download in a delegate class with outlets for UI controls. But for some reason controls don't respond to direct messages from the delegate.

//Header of the delegate
@interface GrooveOnDownload : NSObject {
IBOutlet id downloadButton;
//...

//Implementation 
//...
[downloadButton setEnabled:FALSE]; // Doesn't work
//...

Any ideas?

It is my fourth day of Mac development so I don't know much about the platform.

Edit : 2010-05-28 01:03:41.486 GrooveOnLite[3303:a0f] Download button = (null)

Edit 2 :

Can't access UI from a delegate?

Edit 3 : I miss Windows .....

Edit 4 In Win32 you send one window message to the button. Everything is handled by WndProc loop. It is damn simple. In Mac you have this magical interface builder which somehow gets all that crap working. The delegate gets cal开发者_开发问答led by some withcraft magic. The rest of the classes are connected by some 'magical' force. In windows there is an tmain function which is the entry point. That's it! No retarded outlets and such shit.


I know it sounds obvious, but is everything connected correctly in Interface Builder?

Edit

If the download is on a separate thread, then fbrereto is correct and you'll need to perform the selector on the main thread. Your code would need to be changed to look like this:

[downloadButton performSelectorOnMainThread:@selector(setEnabled:)
    withObject:[NSNumber numberWithBool:NO]
    waitUntilDone:YES];

A few notes: in Objective-C the keyword NO is used instead of FALSE. It's a primitive type, so in order to use it here we had to box it in a NSNumber object. The waitUntilDone argument does exactly what you would expect, and you can change that to NO if you'd rather not wait.

Edit 2

Here's a more complete code example about how to accomplish what I think you want, which is to reuse a single instance of GrooveOnDownload from your app delegate. I'm assuming that your app delegate class is called GrooveOnLiteAppDelegate.

// GrooveOnLiteAppDelegate.h
@interface GrooveOnLiteAppDelegate : NSObject
{
    IBOutlet GrooveOnDownload *grooveOnDownload;
    // other properties go here
}

// your method signatures go here
@end

// GrooveOnLiteAppDelegate.m
@implementation GrooveOnLiteAppDelegate

- (void)mySuperAwesomeMethod
{
    // it's up to you to figure out what method to put this in and
    // how to call it
    NSURLDownload *dw = [[NSURLDownload alloc] initWithRequest:request delegate:grooveOnDownload];
}

@end

Given that code in your app delegate, you'll have an outlet in IB that you can connect to your GrooveOnDownload object in IB. If you do that, then grooveOnDownload will be a pointer to that object.


All UI calls have to be made on the main thread; if the download is happening in the background your delegate may be getting notified on a thread other than the main one, in which case a call to a UI element would have to be done through something like -[NSObject performSelectorOnMainThread:withObject:waitUntilDone:modes: or another related API.

0

精彩评论

暂无评论...
验证码 换一张
取 消