2009-07-24 3 views
1

는 좀 아이폰 프로그래밍에 내 손을 시도하고하지 않습니다와 나는 베테랑 상당히 분명있을 수 있습니다 뭔가에 걸쳐 실행했습니다하지만 난 그게 무슨 일이 일어나고 이유는 정확히 모르겠어요. 두 개의 UIViewController 클래스가 있고 다른 클래스의 메서드에 액세스하려고합니다. 두 NSObject 클래스 IB (둘 다 각각에 대한 UpdateClass 같은 클래스 파일) 함께 IB와 관련된 및 클래스를 만들고 메서드를 호출하려면 노력하고있어. 꽤 쉽지만, 문제는 NSLog에 따라 메서드를 호출하지만 레이블을 업데이트하지 않는다는 것입니다. 여기 내 코드는 다음과 같습니다.아이폰 - 사용자 정의 클래스 액세스 방법

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

@interface UpdateClass : NSObject { 
    IBOutlet UILabel *lbl1; 
    IBOutlet UILabel *lbl2; 
} 

@property (nonatomic, retain) IBOutlet UILabel *lbl1; 
@property (nonatomic, retain) IBOutlet UILabel *lbl2; 

- (void)updateLabels; 

@end 

//UpdateClass.m 

#import "UpdateClass.h" 

@implementation UpdateClass 

@synthesize lbl1; 
@synthesize lbl2; 


- (void)updateLabels { 
    NSString *someWord = @"Whatever"; // This could be anything 
    NSLog(@"NSObject Update"); 
    [lbl1 setText:someWord]; 
    [lbl2 setText:someWord]; 
} 


@end 

//ViewController1.h 
#import <UIKit/UIKit.h> 
@class UpdateClass; 
@interface ViewController1 : UIViewController { 
IBOutlet UIButton *button1; 
NSObject *UpdateClassObject; 
UpdateClass *updateClass; 
} 
@property (nonatomic, retain) IBOutlet UIButton *button1; 
@property (nonatomic, retain) NSObject *UpdateClassObject; 
@property (nonatomic, retain) UpdateClass *updateClass; 
- (void)updateLabels:(id)sender; 
@end 

//ViewController1.m 
#import "ViewController1.h" 
#import "UpdateClass.h" 

@implementation ViewController1 
@synthesize button1; 
@synthesize UpdateClassObject; 
@synthesize updateClass; 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    updateClass = [[UpdateClass alloc] init]; 
} 

- (void)updateLabels:(id)sender; { //This is connected to TouchDown on button1 
    NSLog(@"Calls UpdateLabels"); 
    [updateClass updateLabels]; //Calls the class method 
} 

//ViewController2.h 
#import <UIKit/UIKit.h> 
@class UpdateClass; 
@interface ViewController2 : UIViewController { 
IBOutlet UIButton *button2; 
NSObject *UpdateClassObject; 
UpdateClass *updateClass; 
} 
@property (nonatomic, retain) IBOutlet UIButton *button2; 
- (void)updateLabels:(id)sender; 
@end 

//ViewController2.m 
#import "ViewController2.h" 
#import "UpdateClass.h" 

@implementation ViewController2 
@synthesize button2; 
@synthesize UpdateClassObject; 
@synthesize updateClass; 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    updateClass = [[UpdateClass alloc] init]; 
} 

- (void)updateLabels:(id)sender; { //This is connected to TouchDown on button2 
    NSLog(@"Calls UpdateLabels"); 
    [updateClass updateLabels]; //Calls the class method 
} 

따라서 두보기 모두에서 IB에 연결된 NSObject가 있습니다. 각 뷰에는 NSObject와 파일 소유자에게 연결되는 레이블이 있습니다 (둘 다 연결할 수는 없습니다). 버튼을 누르면 (IB에서 제대로 연결되어 있음) 레이블이 일부 문자열로 변경됩니다. NSLog는 메소드가 호출되었다고보고하지만 레이블은 변경되지 않습니다. 여기 뭐가 잘못 됐니?

(참고 :이 코드 중 일부를 입력해야하므로 약간의 실수가있을 수 있습니다. 지금은 나와 함께 모든 코드가 없기 때문입니다.)

+0

메신저 그냥 레이블을 유지하고 업데이트하는 클래스를 사용하는 이유를 궁금해? 또한 UIViewControllers 뷰에 해당 클래스의 레이블을 추가 할 것인지 궁금합니다. – Daniel

+0

업데이트 처리를위한 일종의 집중식 클래스를 생각했기 때문에 ...하지만 Objective-C 프로그래밍이 어떻게되어 있는지 이해하지 못하고 있습니다. 작업. –

+0

정말 그럴 필요가 없습니다. UIViewCOntroller에서 레이블을 직접 처리 할 수 ​​있습니다. 뷰를 관리하기 위해 컨트롤러가있는 것은 무엇입니까? – Daniel

답변

0

NSLog()가 실행되었지만 레이블이 업데이트되지 않으면 거의 확실하게 lbl1lbl2은 0입니다. 실제로는 IB로 연결되어 있지 않기 때문에 거의 확실합니다. 또는 -viewDidLoad 실행 전에이 코드를 실행하고 있기 때문에 거의 확실합니다. 뷰를 실제로로드하고 콘센트에 연결하기 전까지는 디자인에서 -updateLabels을 피해야합니다. 뷰는 느리게로드되므로 뷰를 처음으로 표시하기 전까지 이러한 레이블이 만들어지지 않습니다.

짧은 버전은 -updateLabels-viewDidLoad에 불러야한다는 것입니다.

+0

값이 변경되면 어떻게 처리해야합니까? 마찬가지로 실제 프로그램에서 someWord 문자열은 변화하는 변수 일 수 있습니다. 이것은 라벨의 텍스트를 상당히 자주 바꾸는 프로그램을 설치하는 나쁜 방법입니까? –

+0

텍스트가 자주 변경되는 경우 알림을 사용하여 UI 요소를 최신 상태로 유지해야합니다. 당신이 나타내는 데이터를 가지고있는 Model 객체가 있어야합니다. 데이터가 변경되면 알림이 게시됩니다. ViewController가 보이면 (그리고 보이는 경우에만), 알림을 관찰하고 레이블을 업데이트하여 새로운 값과 일치시켜야한다. 알림을 구독하고 구독을 취소하려면 -viewWillAppear/Disappear를 사용해야합니다. http://developer.apple.co.kr/documentation/Cocoa/Conceptual/Notifications/http://robnapier.net/blog/thoughts-nsnotifications-42 –

0

이 코드의 여러 측면이 혼란 스럽기 때문에 객체와 클래스 사이의 명백한 차이점부터 살펴 보겠습니다. 그것이 무엇

NSObject *UpdateClassObject; 

입니다 :

의 목적은 무엇인가? 어떻게 배정 되나요? 전혀 거기에 왜 당신은 전 그렇게 잘 모르겠어요 사용하는 것으로 표시되지 않습니다

UpdateClass *updateClass; 

: 이름에서, 당신이 단지의 목적은 당신의 UpdateClass 클래스의 인스턴스를 원하는 것 같다 .

자 이제 문제의 핵심에 대해 : [updateClass updateLabels]을 호출하고 NSLog 문이 실제로 호출되고 있음을 나타냅니다. 어느 것이 가장 가능성있는 문제는 레이블 lbl1lbl2의 인스턴스가 모두 nil이라는 것입니다. Objective-C에서 nil으로 메시지 (예 : updateText:)를 보내면 오류가 발생하지 않으며 자동으로 실패합니다.

그렇다면 왜 그것들은 0입니까? 글쎄, 그들은 나에게 당신이 그 파일의 소유자 당신의 멤버 변수에 일부 UILabel의 실제 배선을하지 UpdateClass 인 NIB 파일을 가지고 생각하게 IBOutlet들로 선언된다.

updateClass = [[UpdateClass alloc] initWithNibName:@"UpdateClass" bundle:nil]; // or whatever the nib is called 

그러나 당신이 실제로하고있는 것은 :이 맞다면, 당신은 제대로 NIB와 updateClass을 initialze 필요

updateClass = [[UpdateClass alloc] init]; 

이 클래스는 NIB로부터 초기화되지 않습니다 것을 의미하여 라벨은 결코 유선이 아닙니다.

마지막으로 클래스 이름에 'Class'라는 단어를 사용하는 것이 하나의 클래스입니다. 분명히 클래스입니다. 이는 또한 UpdateClass이라는 인스턴스를 저장하고있는 인스턴스 변수를 updateClass이라고 부르면 혼동을 일으킬 수 있습니다. 이것은 실제로 유형이 Class[SomeClass class]을 호출하여 얻을 수있는 객체의 인스턴스를 저장한다는 것을 의미합니다.

0

잘못된 UpdateClass로 updateLabels 메시지를 보내고 있습니다.

당신은 InterfaceBuilder에서 UpdateClass의 인스턴스를 연결했는데 IB에 설정된 레이블에도 연결되어 있다고 말했습니까? 따라서 뷰가로드 될 때 UpdateClass 객체가 이미 NIB에서 삽입됩니다.

viewDidLoad 구현에서 UpdateClass의 새 인스턴스를 만듭니다. 이 인스턴스에는 레이블이 설정되어 있지 않습니다 (레이블이 없습니다). 따라서 updateLabels 메서드를 해당 객체에 보내면 해당 객체에는 업데이트 할 레이블이 없습니다.

viewDidLoad에서 updateClass 선언 및 할당을 버리고 updateClassObject에 updateLabels 메시지를 보냅니다. UpdateCLassObject 멤버를 updateClass로 이름을 바꾸거나 더 나은 이름으로 변경하고 클래스 이름을 updater와 같은 것으로 변경하십시오. 대신 기본 클래스를 사용하는 것도 고려하십시오.

1

여기 디자인에 단어 :

당신은 두 개 이상의 뷰 컨트롤러 구현 중 일부 기능을 공유 할 것으로 보인다. 이 경우 UIViewController에서 파생 된 공통 기본 클래스를 만들어 해당 클래스에서 두 개의 뷰를 파생시킬 수 있습니다. BaseView는 IB에서 연결할 수있는 일반적인 UI 구성 요소의 콘센트를 선언합니다.

@interface BaseUIViewController : UIViewController { 
    IBOutlet UILabel *lbl1; 
    IBOutlet UILabel *lbl2; 
} 

@property (nonatomic, retain) IBOutlet UILabel *lbl1; 
@property (nonatomic, retain) IBOutlet UILabel *lbl2; 

- (void)updateLabels; 

@end 

...

@interface ViewController1 : BaseUIViewController { 
    IBOutlet UIButton *button1; 

...

관련 문제