2014-03-13 19 views
0

我有一個按鈕,我試圖設置線程完成時的圖像。我的代碼似乎沒用,只是改變圖像按鈕,但這是爲了練習,並進入更大的事情。ObjectiveC在線程完成時設置圖像

目標:將b0的圖像設置爲button_x.png(在項目中找到)。

問題:按鈕圖像並沒有改變,如果我做的故事板到ViewController按鈕聲明我得到一個崩潰與-[UIButton setImage:]: unrecognized selector sent to instance 0x8b4c270發現按鈕之間的連接。

謝謝。

ViewController.h:

@interface ViewController : UIViewController { 
    IBOutlet UIButton *b0; 
    Game *instanceOfGame; 
} 

@property (nonatomic, strong) UIButton *b0; 
@property (nonatomic, strong) Game *instanceOfGame; 

@end 

ViewController.m:

#import "ViewController.h" 

@interface ViewController() 

@end 

@implementation ViewController 
@synthesize instanceOfGame; 
@synthesize b0; 
static NSString *postName = @"123"; 


- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(post:) name:postName object:nil]; 
    instanceOfGame = [[Game alloc] init]; 
    [instanceOfGame start]; 
} 

- (void) post: (NSNotification *) result { 
    NSNumber *str = [result object]; 
    if (str == 0) { 
     [self.b0 performSelectorOnMainThread:@selector(setImage:) withObject:[UIImage imageNamed:@"button_x.png"] waitUntilDone:NO]; 
    } 

} 

- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 

@end 

Game.h:

#import <Foundation/Foundation.h> 

    @interface Game : NSObject 
    @property (nonatomic, strong) NSNumber *choice; 
    @property (nonatomic, strong) NSNotificationCenter *ns; 
    -(void) start; 
    @end 

Game.m:

#import "Game.h" 

@implementation Game 

NSNotificationCenter *ns; 
@synthesize ns; 
@synthesize choice; 
static NSString *postName = @"123"; 

-(id) init { 
    if (self = [super init]) { 
     ns = [NSNotificationCenter defaultCenter]; 
    } 
    return self; 
} 

-(void) start { 
    [self performSelectorInBackground:@selector(loadData) withObject:Nil]; 
} 

-(void) loadData { 
    choice = 0; 

    [ns postNotificationName:postName object:choice]; 
} 

@end 

回答

2

的UIButton沒有一個setImage:函數,因而引發異常。

它確實有這個功能,但:

- (void)setImage:(UIImage *)image forState:(UIControlState)state 

嘗試更換:

[self.b0 performSelectorOnMainThread:@selector(setImage:) withObject:[UIImage imageNamed:@"button_x.png"] waitUntilDone:NO]; 

具有相似類型的實現使用GCD調用正確的函數來完成:

dispatch_async(dispatch_get_main_queue(), ^{ 
    [self.b0 setImage:[UIImage imageNamed:@"button_x.png"] forState:UIControlStateNormal]; 
}); 
+0

哇工作,真棒感謝!你介意解釋dispatch_async與我遇到的問題之間的區別嗎? – StackPWRequirmentsAreCrazy

+0

當然!dispatch_async和dispatch_sync是兩條命令,可讓您將代碼發送到另一個線程。在上面的例子中,我發送塊中的代碼(^ {}內的部分,塊是Obj-C的另一個特性)到主線程(dispatch_get_main_queue())。我在這裏使用了dispatch_async,同步和異步之間是同步等待內部完成的代碼,異步不會。它基本上等同於waitUntilDone。 –

+0

非常好的解釋,非常感謝! – StackPWRequirmentsAreCrazy

1

嘗試這,

if (str == 0) { 
    dispatch_sync(dispatch_get_main_queue(), ^{ 
     [self.b0 setImage:[UIImage imageNamed:@"button_x.png"] forState:UIControlStateNormal];  
    }); 
} 
3

@Colin Cornaby說寫。

UIButton沒有setImage方法。

您也可以使用相同的現有代碼。略低於線

[self.b0 performSelectorOnMainThread:@selector(setImage:) withObject:[UIImage imageNamed:@"button_x.png"] waitUntilDone:NO]; 

更新爲

[self performSelectorOnMainThread:@selector(setImage:) withObject:[UIImage imageNamed:@"ListDropDown.png"] waitUntilDone:NO]; 

,然後定義方法setImage:

-(void)setImage:(UIImage *)img 
{ 
    [self.bo setImage:img forState:UIControlStateNormal]; 
} 

我希望它會爲你