Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 委托并执行SelectorOnMainThread_Iphone_Multithreading_Uiview_Delegates_Nsnotifications - Fatal编程技术网

Iphone 委托并执行SelectorOnMainThread

Iphone 委托并执行SelectorOnMainThread,iphone,multithreading,uiview,delegates,nsnotifications,Iphone,Multithreading,Uiview,Delegates,Nsnotifications,我对这两个词的用法有点困惑 我有一个后台线程,负责下载数据并将其应用到iOS设备内的核心数据数据库 后台线程中的代码调用共享实例类ProgressController来更新UI上的进度(我知道它在主线程中运行)。ProgressController然后有一个委托,该委托由顶部的视图控制器分配 除了后台线程启动后UI不会更新之外,一切正常。我知道正在调用委托,因为我有NSLogs,其中包含正在传递的文本 现在我读到我应该使用performSelectorOnMainThread,但考虑到委托正在触

我对这两个词的用法有点困惑

我有一个后台线程,负责下载数据并将其应用到iOS设备内的核心数据数据库

后台线程中的代码调用共享实例类ProgressController来更新UI上的进度(我知道它在主线程中运行)。ProgressController然后有一个委托,该委托由顶部的视图控制器分配

除了后台线程启动后UI不会更新之外,一切正常。我知道正在调用委托,因为我有NSLogs,其中包含正在传递的文本

现在我读到我应该使用performSelectorOnMainThread,但考虑到委托正在触发,这似乎是多余的

我应该改用performSelectorOnMainThread,而不使用委托吗

我错过什么了吗

如果有人能解释,我会非常感激

谢谢

克里斯

在后台线程中

progressController = [ProgressController sharedInstance];
[progressController open];

在ProgressController.h中

#import <Foundation/Foundation.h>

@protocol ProgressControllerDelegate 
@required
- (void) displayProgress:(NSString *)text;
- (void) showProgress;
- (void) hideProgress;

@end

@interface  ProgressController : NSObject {

    NSString    *currentProgress;
    BOOL        progressOnDisplay;
    id          delegate;
}

+ (ProgressController *)sharedInstance;

@property (nonatomic) BOOL  progressOnDisplay;
@property (nonatomic, assign) id delegate;

-(void) open;
-(void) updateProgress:(NSString *)text;
-(void) reDisplayProgress;
-(void) close;

@end
视图控制器内部

- (void)viewDidLoad {
    [super viewDidLoad];

    progressController = [ProgressController sharedInstance];
    progressController.delegate = self;
    [progressController reDisplayProgress]; // In case progress has been updated prior to the view load

}

// Delegate method to show Progress Label
- (void) showProgress {
    progressView.hidden = FALSE;    

}

// Delegate method to display specific text in Progress label
- (void) displayProgress:(NSString *)text {
    [progressLabel setText:text];
    [progressView setNeedsDisplay];

    DLog(@"Reporting -  %s", [text UTF8String]);  // I can see that this is firing successfully

}

// Delegate method to hide Progress Label
- (void) hideProgress {
    progressView.hidden = TRUE;

}

您应该使用NSURLConnection类异步下载数据,然后可以使用其委托方法更新UI

请参阅本守则-

    // create the URL
    NSURL *postURL = [NSURL URLWithString:@"http://twitpic.com/api/uploadAndPost"];

    // create the connection
    NSMutableURLRequest *postRequest = [NSMutableURLRequest requestWithURL:postURL
                                                               cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                           timeoutInterval:30.0];

    // change type to POST (default is GET)
    [postRequest setHTTPMethod:@"POST"];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:postRequest delegate:self];

    if( theConnection )
    {
        webData = [[NSMutableData data] retain];
    }
委托方法-

-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    [webData setLength: 0];
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
// update your UI here.. 
    [webData appendData:data];
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    NSLog(@"ERROR with theConenction");
    [connection release];
    [webData release];
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
//  your data downloaded completely.. do you code here.. 

}

委托方法本身与线程没有特定的关系。它只是一个对象向另一个对象发送消息。如果该委托方法恰好在后台线程上被调用,那么任何UI交互都必须在主线程上完成

有关更多信息,请参阅文档:

某些对象将委托调用与特定线程相关联。例如,NSURLConnection的
+connectionWithRequest:delegate:
,其文档说明:

发送给委托的消息将在调用此方法的线程上发送。要使连接正常工作,调用线程的运行循环必须在默认运行循环模式下运行


因此,简而言之,是的,可以同时使用委托方法和
performSelectorOnMainThread
来更新UI。这样做没有错。

插入的代码显示您直接从后台线程调用委托方法。要在主线程上执行GUI工作(您应该这样做),您需要在调用委托的方法时直接使用
performSelectorOnMainThread:
,或者在委托方法本身中使用。如果您想在这些更新过程中停止后台线程,您可以使用带有
waitUntilDone:YES

的变体。请在后台线程中显示调用ProgressController方法的代码。谢谢Eiko。例如,在委托(ProgressController.m)中,应该[self.delegate displayProgress:currentProgress];成为[self.delegate:currentProgress]执行SelectorOnMainThread:@selector(displayProgress:)with object:currentProgress waitUntilDone:NO]?它应该类似于[self.delegate performselectornmainthread:@selector(displayProgress:)withObject:currentProgress];(未经测试,仅在此处键入)你是明星Eiko。非常感谢。我在委托中需要的行的格式为[self.delegate performSelectorOnMainThread:@selector(displayProgress:)withObject:currentProgress waitUntilDone:NO];正如您所说,这意味着从主线程调用委托,UI现在更新。现在都在工作。
    // create the URL
    NSURL *postURL = [NSURL URLWithString:@"http://twitpic.com/api/uploadAndPost"];

    // create the connection
    NSMutableURLRequest *postRequest = [NSMutableURLRequest requestWithURL:postURL
                                                               cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                           timeoutInterval:30.0];

    // change type to POST (default is GET)
    [postRequest setHTTPMethod:@"POST"];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:postRequest delegate:self];

    if( theConnection )
    {
        webData = [[NSMutableData data] retain];
    }
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    [webData setLength: 0];
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
// update your UI here.. 
    [webData appendData:data];
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    NSLog(@"ERROR with theConenction");
    [connection release];
    [webData release];
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
//  your data downloaded completely.. do you code here.. 

}