2014-03-26 3 views
0

내 NSData 클래스의 UIViewController에있는 모든 레이블, 슬라이더 및 스위치에 액세스 할 수 없습니다.NSObject 클래스에서 UISwitch 상태 변경

FirstViewController.h

@interface FirstViewController : UIViewController 
@property (strong) IBOutlet UISwitch * mySwitch; 
@property (strong) IBOutlet UISlider *myTransitionSlide; 
@property (nonatomic,retain) IBOutlet UILabel *labelTest; 

myNSDataClass.h

#import <Foundation/Foundation.h> 
#import <CoreBluetooth/CoreBluetooth.h> 
@class FirstViewController; 


@interface myNSDataClass : NSObject <UIApplicationDelegate,CBPeripheralManagerDelegate> 
{ 
    FirstViewController *firstViewController; 
} 
@property (nonatomic, retain) FirstViewController *firstViewController; 

myNSDataClass.m

이 지금까지 내 코드입니다

- (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveWriteRequests:(NSArray *)requests 
{ 
    self.firstViewController = [[FirstViewController alloc]init]; 
    [[self.firstViewController labelTest]setText:@"text changed"];             
    [self.firstViewController.myTransitionSlide setValue:1]; 
    [self.firstViewController.mySwitch setOn:NO animated:YES]; 
} 

문제는 FirstViewController의 재 할당에서 비롯된 것으로 알고 있지만 무엇을해야할지 모르겠습니다.

답변

3

다른 곳에서 콘센트에 액세스하지 말고 콘센트를 소유 한보기 컨트롤러에서 액세스하지 마십시오. 또한 콘센트를 weak으로 만들고 싶습니다.

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    [[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(handleDidReceiveWriteRequestNotification:) 
               name:@"MyAppDidReceiveWriteRequestNotification" 
               object:nil]; 

} 

그리고 당신 : 당신이 viewDidLoad 예를 들면, 그 통지의 관찰자로서 자신을 등록하여 FirstViewController에, 그리고

- (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveWriteRequests:(NSArray *)requests 
{ 
    [[NSNotificationCenter defaultCenter] postNotificationName:@"MyAppDidReceiveWriteRequestNotification" 
                 object:nil 
                userInfo:@{@"text": @"text changed", @"switchOn": @(NO)}]; 
} 

:

알림을 사용할 수 있습니다 문제를 해결하기 위해 핸들러 구현 :

- (void)handleDidReceiveWriteRequestNotification:(NSNotification *)note 
{ 
    [self.labelTest setText:note.userInfo[@"text"]]; 
    [self.mySwitch setOn:[note.userInfo[@"switchOn"] boolValue] animated:YES]; 
} 

그리고 당신은 청소 :

- (void)dealloc 
{ 
    [[NSNotificationCenter defaultCenter] removeObserver:self]; 
} 

그것이 맞습니다. 훨씬 더 청결한.

또한 코드의 여러 위치에서 동일한 문자열 리터럴을 갖지 않도록 알림 이름과 userInfo 사전 키 이름을 상수로 변경하려고합니다.

+1

이것은 가장 깨끗한 해결책입니다. 고맙습니다. –

1

FirstViewController에 대한 참조를 추가하여 사용할 수 있습니다. FirstViewController.m에서 예컨대, myNSDataClass 객체의 속성 또는 전용 변수를 추가

//FirstViewController.m 
@implementation FirstViewController { 
    myNSDataClass *_myData; 
} 

이상있는 viewDidLoad에 FirstViewController 참조를 추가

-(void)viewDidLoad { 
    //Your code here... 
    _myData = [[myNSDataClass alloc] init]; 
    _myData.firstViewController = self; 
} 

다음 단계는 제거하고 메모리 누출을 변경하여 myNSDataClass.h to : @class FirstViewController; 적은 4

+0

myNSDataClass 객체를 할당 할 때 무언가를 잘못 할당하는 문제가 있습니다. –

+0

그러나 모든 IOS의 2-3 %에 설치된 iOS 4.3 이전의 iOS 버전은 공식적으로 지원되지 않습니다 장치. OS가 4보다 적은 지원에 대해 언급 할 때 어떤 이야기를하고 있습니까? –

+0

@SergiusGee 나는 ARC를 지원하는 IOS 4.3에 대해 말하고있다. OS가 4.3 이하이면 약한 키워드를 사용할 수 없다. – Greg

1

당신은 문제가 재 할당에서 오는 것을 알고, 다음 재 할당하지 않는 OS를 지원하지 않는 경우

@interface myNSDataClass : NSObject <UIApplicationDelegate,CBPeripheralManagerDelegate> 
@property (nonatomic, weak) FirstViewController *firstViewController; //<- use assign if you support OS < 4 
//your code .. 
@end 

당신은 구현 파일에 @synthesize 필요하지 않습니다 그것. 간단합니다. :-)

대신 myNSDataClassfirstViewController 속성을 설정해야합니다. 귀하의 firstViewController이 실제로 인스턴스화 된 바로 그 순간에 그러한 일이 발생할 수 있습니다. 그 위치는 앱의 아키텍처에 따라 다릅니다.

'깔끔한'경우 myNDataClass (모델의 역할을 할 수 있음)에 mySwitch 등을 직접 입력하지 마십시오. firstViewController의 몇 가지 메소드를 호출합시다. 뷰 컨트롤러 만 컨트롤을 "알기"만하고 그에 맞게 설정합니다.

firstViewController.h에서이 방법을 선언하는 것이 트릭을 수행해야합니다. 그러나 firstViewController이 구현 (확인)하는 프로토콜로 선언하면 더 낫습니다. myNSDataClass.hfirstViewConroller.h을 포함하는 대신이 프로토콜 (.h 파일도 포함)을 포함해야합니다.

1

앞에 [self.firstViewController.mySwitch setOn:NO animated:YES]; 앞에 중단 점을 설정하면 문제를 발견해야합니다. self.firstViewController.mySwitch을 인쇄 할 경우, 요소는 이 아닌이어야합니다.

그래서이 시점 예를 들어

에서 원시 또는 초기화 속성을 설정하려고

// FirstViewController.h

@interface FirstViewController : UIViewController 
{ 
    BOOL switchState; 
    NSString *lblTitle; 
    float sliderValue; 
} 

-(void)setSwitchState:(BOOL)pSwitchState andLabelText:(NSString *)pLblTitle andSliderValue:(float)pSliderValue; 

// FirstViewController.m

-(void)setSwitchState:(BOOL)pSwitchState andLabelText:(NSString *)pLblTitle andSliderValue:(float)pSliderValue 
{ 
    switchState = pSwitchState; 
    lblTitle = pLblTitle; 
    sliderValue = pSliderValue; 
} 

-(void)viewWillAppear:(BOOL)animated 
{ 
    [super viewWillAppear:animated]; 
    [self.labelTest] setText:pLblTitle];          
    [self.myTransitionSlide setValue:pSliderValue]; 
    [self.mySwitch setOn:pSwitchState animated:YES]; 
} 

및 주변 기기 관리자

- (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveWriteRequests:(NSArray *)requests 
{ 
    // I don't know if this re-initialization is realy required, so I let it here. 
    // If not, you should think of init it somewhere else use the solution with the NSNotificationCenter ;) 
    self.firstViewController = [[FirstViewController alloc]init]; 
    self.firstViewController setSwitchState:NO andLabelText:@"text changed" andSliderValue:1]; 
} 
+0

'peripheralManager : didReceiveWriteRequests :'메소드가 호출 될 때마다 여전히'FirstViewController'의 새로운 인스턴스를 생성하고 있습니다. –

+0

나는 코드의 나머지 부분을 알지 못한다. 그래서 나는이 부분을 희망에 남겨 두었다. 그렇게 할 필요가 있고 그는 그가 무엇을하고 있는지를 알고있다.) 그렇지 않으면 나는 또한 위임 솔루션을 추천 할 것이다. – geo

관련 문제