【问题标题】:Calling navigation controller method from background operation从后台操作调用导航控制器方法
【发布时间】:2011-03-10 02:54:51
【问题描述】:

我正在使用 NSOperation 运行后台操作,该操作从我的 AppDelegate 启动。我要做的是在操作完成后,让它调用 RootViewController.m 文件中的方法。

目前我的 AppDelegate 中有一个名为 navigationController 的属性,我一直在尝试像这样设置调用:

AppDelegate.m:

GetRSSOperation *gro = [[GetRSSOperation alloc] initWithURL:rssURL target:self selector:@selector(dataSourceDidFinishLoadingNewData:)];
    [queue addOperation:gro];
    [gro release];

GetRSSOperation.m:

[target performSelectorOnMainThread:selector withObject:alerts waitUntilDone:YES];

我尝试将目标设置为 self、self.navigationController、self.navigationController.view,但没有任何效果。

我知道这个问题可能是由于我还没有完全了解整个 ios 架构,所以请多多指教。

**添加更多代码说明:

AppDelegate.h

#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>


@interface AppDelegate : NSObject {
    NSOperationQueue *queue;
    UIWindow *window;
    UINavigationController *navigationController;

    NSURL *rssURL;

    // storage for the alert list from RSS feed
    NSMutableArray *alerts;     
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
@property (nonatomic, retain) NSMutableArray *alerts;
@property (nonatomic, retain) NSURL *rssURL;
@property (retain) NSOperationQueue *queue;


+ (id)shared;
@end

AppDelegate.m

#import "AppDelegate.h"
#import "RootViewController.h"
#import "AlertViewController.h"
#import "RefreshTableHeader.h"
#import "GetRSSOperation.h"

@implementation AppDelegate
static AppDelegate *shared;

@synthesize window, navigationController, alerts;


- (id)init
{
    if (shared) {
        [self autorelease];
        return shared;
    }
    if (![super init]) return nil;

    queue = [[NSOperationQueue alloc] init];
    shared = self;
    return self;
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

        // Add the navigation controller's view to the window and display.
        UIImageView *imageview=[[UIImageView alloc]initWithFrame:CGRectMake(270, 3, 37, 37)];
        imageview.image=[UIImage imageNamed:@"iphone.png"];
        [self.navigationController.navigationBar addSubview:imageview]; 
        [self.window addSubview:navigationController.view];
        [self.window makeKeyAndVisible];

        if (rssURL == nil) {
            NSString *alertAddress = @"http://www.compoundstockearnings.com/com/public/selections.cfc?method=getrss&email=";
            alertAddress = [alertAddress stringByAppendingString:cseLogin];
            alertAddress = [alertAddress stringByAppendingString:@"&password="];
            alertAddress = [alertAddress stringByAppendingString:csePass];      
            rssURL = [[NSURL alloc] initWithString:alertAddress];
        }

        GetRSSOperation *gro = [[GetRSSOperation alloc] initWithURL:rssURL target:self selector:@selector(dataSourceDidFinishLoadingNewData:)];
        [queue addOperation:gro];
        [gro release];      
        return YES;
    }
    return NO;
}
@end

GetRSSOperation 只是进行 rss 调用,将其放入内存然后尝试调用主导航控制器:

[target performSelectorOnMainThread:selector withObject:alerts waitUntilDone:YES];

我希望事物在其上执行选择器的主导航控制器如下所示:

RootViewController.h

#import <UIKit/UIKit.h>

@interface RootViewController : UITableViewController {
    IBOutlet RefreshTableHeader *alertTable;

    UIImageView *imageView; 

}

@end

RootViewController.m:
#import "RootViewController.h"
#import "AppDelegate.h"

@implementation RootViewController

- (void)dataSourceDidFinishLoadingNewData:(NSMutableArray *)tempAlerts 
{
    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    appDelegate.alerts = tempAlerts;
    reloading = NO;
    [alertTable flipImageAnimated:NO];
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:.3];
    [self.tableView setContentInset:UIEdgeInsetsMake(0.0f, 0.0f, 0.0f, 0.0f)];
    [alertTable setStatus:kPullToReloadStatus];
    [alertTable toggleActivityView:NO];
    [UIView commitAnimations];
    [popSound play];
}

显然我已经将它缩短了一点,但这就是它的核心。我只希望 GetRSSOperation 能够调用 RootViewController.m - dataSourceDidFinishLoadingNewData。任何意见表示赞赏。

【问题讨论】:

    标签: iphone objective-c ios background nsoperation


    【解决方案1】:

    听起来您在弄清楚如何正确格式化对performSelectorOnMainThread:withObject:waitUntilDone: 的调用时遇到了一些麻烦。这很简单,真的。 如果你通常会这样调用方法:

    [target method:alerts]
    

    您像这样格式化 performSelector 调用:

    [target performSelectorOnMainThread:@selector(method:) withObject:alerts waitUntilDone:YES];
    

    【讨论】:

    • 是的,我理解那部分,我实际上是在将目标和选择器传递给 GetRSSOperation。我的问题是它没有执行它,所以我假设我的目标是错误的......
    • 然后发布更多代码。将您现有的代码简化为一个测试用例,它只会说明问题,但实际上确实说明了问题。
    • 方法dataSourceDidFinishLoadingNewData:在RootViewController上,所以你需要为target传递一个该类的实例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-13
    • 2013-10-05
    • 2014-01-26
    • 1970-01-01
    • 2014-07-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多