Note that there are some explanatory texts on larger screens.

plurals
  1. POperformSelectorOnMainThread results in "unrecognized selector sent to instance"
    primarykey
    data
    text
    <p>Firstly thanks in advance for your time looking at this question.</p> <p>I'm trying to create a very simple UIViewController example, where I load the data in a thread. The thread is getting called but from that thread, I can't get back to the main thread. The test case below is extremely simple, I create a View based application in XCode and just added the NSOperationQueue code. Hopefully someone can quickly spot my schoolboy error :)</p> <p>The delegate is very simple, .h is:</p> <pre><code>#import&lt;UIKit/UIKit.h&gt; @class ViewbasedViewController; @interface ViewbasedAppDelegate : NSObject &lt;UIApplicationDelegate&gt; { UIWindow *window; ViewbasedViewController *viewController; } @property (nonatomic, retain) IBOutlet UIWindow *window; @property (nonatomic, retain) IBOutlet ViewbasedViewController *viewController; @end </code></pre> <p>And the .m is equally simple:</p> <pre><code>#import "ViewbasedAppDelegate.h" #import "ViewbasedViewController.h" @implementation ViewbasedAppDelegate @synthesize window; @synthesize viewController; #pragma mark - #pragma mark Application lifecycle - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. // Set the view controller as the window's root view controller and display. self.window.rootViewController = self.viewController; [self.window makeKeyAndVisible]; return YES; } </code></pre> <p>Now to the question. I want to run a thread when the view is loaded. I've defined an NSOperationQueue in my viewcontroller.h file:</p> <pre><code>@interface ViewbasedViewController : UIViewController { NSOperationQueue *folderQueue; } </code></pre> <p>And in my view controller.m, I want to run some code in a thread once the view is loaded. So inside viewDidLoad I add an operation to a queue: </p> <pre><code>- (void)viewDidLoad { [super viewDidLoad]; // create a thread and run it folderQueue = [[NSOperationQueue alloc] init]; folderQueue.maxConcurrentOperationCount = 1; NSLog(@"about to run thread"); [folderQueue addOperation:[[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(MyThreadedCode) object:nil] autorelease]]; </code></pre> <p>}</p> <p>The function "MyThreadedCode" gets called ok, I can see the debug in the console.</p> <pre><code>-(void)MyThreadedCode { NSLog(@"Start of thread"); [self performSelectorOnMainThread:@selector(reloadMyData) withObject:nil WaitUntilDone:YES]; // [self reloadMyData]; NSLog(@"CALLED REFRESH"); } -(void)reloadMyData { NSLog(@"Request to reloadData"); } </code></pre> <p>BUT...if, from my thread, I try and call a selector on the main thread (for instance I may want to reload data in a tableview), I get an exception. I only get this if I run it using performanceSelectorOnMainThread. If I run </p> <pre><code>[self reloadMyData]; </code></pre> <p>The console looks good:</p> <pre><code>[Session started at 2011-09-06 13:56:50 +0100.] 2011-09-06 13:56:52.258 Viewbased[1618:207] about to run thread 2011-09-06 13:56:52.266 Viewbased[1618:5d03] Start of thread 2011-09-06 13:56:52.270 Viewbased[1618:5d03] Request to reloadData 2011-09-06 13:56:52.272 Viewbased[1618:5d03] CALLED REFRESH </code></pre> <p>If I use </p> <pre><code>[self performSelectorOnMainThread:@selector(reloadMyData) withObject:nil WaitUntilDone:YES]; </code></pre> <p>I get an unrecognized selector:</p> <pre><code>[Session started at 2011-09-06 13:29:14 +0100.] 2011-09-06 13:29:26.216 Viewbased[1581:207] about to run thread 2011-09-06 13:29:26.224 Viewbased[1581:5d03] Start of thread 2011-09-06 13:29:26.228 Viewbased[1581:5d03] -[ViewbasedViewController performSelectorOnMainThread:withObject:WaitUntilDone:]: unrecognized selector sent to instance 0x4e43060 2011-09-06 13:29:26.235 Viewbased[1581:5d03] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[ViewbasedViewController performSelectorOnMainThread:withObject:WaitUntilDone:]: unrecognized selector sent to instance 0x4e43060' *** Call stack at first throw: ( 0 CoreFoundation 0x00eab5a9 __exceptionPreprocess + 185 1 libobjc.A.dylib 0x00cda313 objc_exception_throw + 44 2 CoreFoundation 0x00ead0bb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187 3 CoreFoundation 0x00e1c966 ___forwarding___ + 966 4 CoreFoundation 0x00e1c522 _CF_forwarding_prep_0 + 50 5 Viewbased 0x000024c3 -[ViewbasedViewController MyThreadedCode] + 78 6 CoreFoundation 0x00e1bc7d __invoking___ + 29 7 CoreFoundation 0x00e1bb51 -[NSInvocation invoke] + 145 8 Foundation 0x000d9495 -[NSInvocationOperation main] + 51 9 Foundation 0x00047b76 -[__NSOperationInternal start] + 747 10 Foundation 0x000477ca ____startOperations_block_invoke_2 + 106 11 libdispatch_sim.dylib 0x01628289 _dispatch_call_block_and_release + 16 12 libdispatch_sim.dylib 0x0162b58a _dispatch_worker_thread2 + 252 13 libSystem.B.dylib 0x9557e781 _pthread_wqthread + 390 14 libSystem.B.dylib 0x9557e5c6 start_wqthread + 30 ) terminate called after throwing an instance of 'NSException' </code></pre> <p>I'm sure its something stupid I've got wrong but I can't see it for looking!!</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload