2014-03-13 5 views
0

스레드가 완료되면 이미지를 설정하려고하는 버튼이 있습니다. 내 코드는 이미지 버튼을 변경하는 것만 큼 쓸모없는 것처럼 보일 수 있지만, 이것은 연습을위한 것이며 더 큰 것으로 진행됩니다.ObjectiveC 스레드가 완료되면 설정 이미지

목표 : b0의 이미지를 button_x.png (프로젝트에 있음)으로 설정합니다.

문제 : 나는 -[UIButton setImage:]: unrecognized selector sent to instance 0x8b4c270와 충돌을 얻을의 ViewController 버튼 선언에 스토리 보드에있는 버튼 사이의 연결을하면 버튼 이미지가 변경되지 않습니다.

감사합니다.

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를 사용했지만 차이점은 sync와 async 사이에 sync가 완료되면 코드가 완료 될 때까지 기다릴 것이고 async는 기다리지 않습니다. 기본적으로 waitUntilDone과 같습니다. –

+0

굉장한 설명, 정말 고마워! – StackPWRequirmentsAreCrazy

1

시도를 this,

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

@ 콜린 코나 비.

UIButton에는 setImage 메서드가 없습니다.

동일한 기존 코드를 사용할 수도 있습니다. 단지

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

로 라인

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

아래에 업데이트 한 다음 방법 setImage를 정의

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

을 내가 당신

관련 문제