2012-03-25 1 views
0

나는 Objective-C를 가르치려고 노력 중이며 연습으로 하나의 버튼과 하나의 라벨로 앱을 작성하려고합니다. 버튼을 클릭하면 계산을 트리거 한 다음 레이블에서 결과를 확인합니다. 다음 코드는 오류나 경고없이 컴파일되고 실행되지만, 알 수있는 한 [object method] 'call'은 아무 것도하지 않습니다. 나는 이것에 시간을 보냈고 무엇이 잘못되었는지 보지 못했습니다. 누구든지 문제를 설명 할 수 있습니까? 감사.메시지에 응답 할 objective-c 객체를 가져올 수 없습니다. 내가 뭘 놓치고 있니?

*** testMethodViewController.h ** * *

#import <UIKit/UIKit.h> 
#import "testBrain.h" 

@interface testMethodViewController : UIViewController 
{ 
    IBOutlet UILabel *display; 
    testBrain *model; 
} 

- (IBAction)cellPressed:(UIButton *)sender; 

@end 

*** testMethodViewController.m ** * *

#import "testMethodViewController.h" 

@implementation testMethodViewController 

- (testBrain *)model 
{ 
    if (!model) {model = [[testBrain alloc] init];} 
    return model; 
} 

- (IBAction)cellPressed:(UIButton *)sender 
{ 
    int x = [model check:3];  //This method call doesn't work. But gets no errors. 
    NSLog(@"Results from model: %i", x); //Says x = 0, but I expect 6 
    NSString *xAsString = [NSString stringWithFormat: @"testBrain: %i", x]; 
    display.text = xAsString; //Label is updated and displays: testBrain: 0 
}        //I expect: testBrain: 6 
@end 

*** testBrain.h ** * *

#import <Foundation/Foundation.h> 

@interface testBrain : NSObject {} 

- (int) check:(int) anInteger; 

@end 

*** testBrain.m ** * *

#import "testBrain.h" 

@implementation testBrain 

- (int) check:(int) anInteger   //3 passed as the parameter. 
{ 
    int r = anInteger + anInteger; 
    NSLog(@"inside check %i", r); //Debugging line: doesn't print. 
    return r; 
} 
@end 

답변

-1

내가 U가 제대로 모두 함께 IBOutlet, IBAction를 & 위임, 데이터 소스를 연결 한 경우

IBOutlet UIButton *button; 

이 또한 확인 파일을 어디서나 testMethodViewController.h을 참조하십시오니까.

+0

잘못되었습니다. 콘센트가 없어도 버튼은 정상적으로 작동합니다.그리고 그는'-cellPressed :'에 의해 인쇄 된'NSLog'를 보았 기 때문에 그의 버튼이 제대로 연결되었는지 확인했습니다. –

0
int x = [model check:3]; 

이 행은 다음과 같습니다

int x = [self.model check:3]; 
1

이 코드를 실행하면 :

int x = [model check:3]; 

modelnil입니다. Objective-C에서 nil으로 보낸 메시지는 아무 것도 처리하지 않고 0을 반환합니다. 따라서 알 수 있듯이 x0이고 -check:은 호출되지 않습니다.

은 분명히이 방법을 기대하고 있었다 자동으로 호출되는 : 당신이 그것을 스스로 할 경우에만

- (testBrain *)model 
{ 
    if (!model) {model = [[testBrain alloc] init];} 
    return model; 
} 

그러나,이 방법은, 호출됩니다 [self model] 또는 self.model을 말해서.따라서이 행은 다음과 같이 수정됩니다.

int x = [[self model] check:3]; 

시도해보십시오.

조금 더 : UIViewController을 만들 때 model 메서드를 완전히 제거하고 인스턴스 변수 model을 만드는 것이 더 명확합니다. 이렇게하면 testMethodViewController 클래스의 코드가 실행될 때마다 model이 유효하다는 것을 보증 할 수 있습니다.

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 
{ 
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 
    if (self) { 
     // Now you can initialize your instance variables 
     model = [[testBrain alloc] init]; 
    } 

    return self; 
} 
+0

깊이있는 설명 주셔서 감사합니다, 커트. 이제 왜 내 코드가하고있는 일을하는지 이해합니다. 네가 옳아. 나는 (testBrain *) 모델이 자동으로 호출 될 것으로 기대하고 있었다. 나는 self.model을 시도했다. 그러나 나는 추측한다. 두 번째 추천에 관해서는, nibNameOrNil은 특별한 용어인가, 아니면 단순히 적절한 nib 파일 이름을 사용할 것인가? 나는 더 많은 독서가있는 것처럼 보이지만 일은 훨씬 더 분명합니다. 다시 한번 감사드립니다. – user1290817

+0

'nibNameOrNil'에 값을 입력하는 것에 대해 걱정할 필요가 없습니다. 단지 인자를 변경하지 않고 바로'super'에 넘겨 주면됩니다. 그 이름에 특별한 것은 없습니다. '- [UIViewController initWithNibName : bundle :] '에 대한 문서를 읽으면 이름을 설명하지만, 여기에있는 것과 전혀 관련이 없습니다. –

0

거의있다 :

당신은 UIViewController 년대를 지정 초기화를 재정 의하여 그렇게 할 것입니다. 이 작업을 완료하려면 @property와 @synthesize를 사용해야합니다. @synthesize 지시문은 컴파일러에게 특정 속성에 대한 setter와 getter를 생성하도록 지시합니다. @synthesize 지시문은 변수가 속성임을 컴파일러에 알려줍니다. 속성을 사용하면 도트 구문을 사용할 수 있습니다. 컨텍스트에 따라 자동으로 getter 또는 setter 메서드를 호출하는 self.model입니다. 당신의 testMethodViewController.h 파일이처럼 보이도록 변경에

:

@interface testMethodViewController : UIViewController 
{ 
    IBOutlet UILabel *display; 
    testBrain *model; 
} 
@property (nonatomic,retain) testBrain *model; 

- (IBAction)cellPressed:(UIButton *)sender; 

@end 

다음하는 .m 구현에 당신은 @implementation 후 @synthesize 사용해야합니다. 이처럼 : 당신의 cellPressed에서 다음

@implementation testMethodViewController 
@synthesize model; // tells the compiler to synthesize the setter and getter for you 
- (testBrain *)model 
{ 
    if (!model) {model = [[testBrain alloc] init];} 
    return model; 
} 

: 방법, 당신은 게터가 호출되는 순서를 self.model를 사용해야합니다 :이 도움이

- (IBAction)cellPressed:(UIButton *)sender 
{ 
    int x = [self.model check:3];  //This method call doesn't work. But gets no errors. 
    NSLog(@"Results from model: %i", x); //Says x = 0, but I expect 6 
    NSString *xAsString = [NSString stringWithFormat: @"testBrain: %i", x]; 
    display.text = xAsString; //Label is updated and displays: testBrain: 0 
}  

희망을.

+0

"속성을 사용하면 도트 구문을 사용할 수 있습니다."- 실제로는 사실이 아닙니다. 'foo.value' 도트 문법은 Obj-C 메소드 호출'[foo value]'를 호출하는 또 다른 방법입니다 (비슷하게'foo.value = x'는'[foo setValue : x]'로 확장됩니다). '@ property'를 통해 선언되지 않은 메소드에 도트 구문을 사용할 수 있습니다. –

+0

그것은 빨랐다! 웬일인지, 나는 나의 모델을 무엇이라도의 자산으로 간주하는 데 어려움을 겪고있다. 나는 @ property/@ synthesize를 다른 것들에 사용했지만 나는 그것을 내 모델에 적용 할 생각은 없다고 생각합니다. 내 속성의 개념을 확장해야 할 것 같아요. 감사. – user1290817

1

model 메서드를 사용하는 경우 Lazy Instantiation의 중간에 있지만 제대로 구현하려면 접근 자 메서드를 통해 지연 인스턴스화 된 객체에 항상 액세스해야합니다. 단추 작업에서이 작업을 수행하지 않으므로 메시지가 무시되고 무시됩니다.

이것은 objective-c의 인스턴스 변수가 선행 또는 후행 밑줄로 선언되는 이유 중 하나입니다. 나머지 클래스에서 model을 입력하면 컴파일러 오류가 발생하여 접근자를 사용해야합니다. 사용자 인터페이스에서

: 구현에서

@property (nonatomic, strong) TestBrain* model; 

: 일반적으로이 속성과 합성 문으로 구현

@synthesize model = model_; 

귀하의 model 방법은 다음과 같습니다

-(TestBrain*)model 
{ 
    if (!model_) 
     model_ = [[TestBrain alloc] init]; 
    return model_; 
} 

그런 다음 모델 전체에서 self.model을 사용합니다. 그는 수업 중 나머지.

방금 ​​시작한 경우 iTunes U의 스탠포드 iOS 과정은 훌륭한 자료이므로 많은 종류의 자료가 다루어집니다.

관련 문제