2012-02-28 4 views
3

이것은 나에게 당황스러워서 내가 뭔가를 놓쳤다 고 생각하게 만듭니다. 하지만 두 개의 창 (SplitViewController와 비슷하지만 몇 가지 중요한 차이점)을 관리하기 위해 뷰 컨트롤러 컨테이너를 만들려고합니다. 나는 간신히 클래스를 구성하기 시작했습니다, 그래서 나는 단지 지금 3 개 인스턴스 변수를 가지고 : UIViewController 하위 클래스에서 인스턴스 변수를 할당 할 수 없습니다.

@implementation SplitViewController{ 
    BOOL _showLeftPane; 
    UIViewController *_leftController; 
    UIViewController *_rightController; 
} 

는 상관없이 내가 뭘, 내가 _leftController 바르에 뷰 컨트롤러를 할당 할 수 없습니다. 주로 _intController iVar에서 할당 할 수 있습니다. 그것은 더 이상해진다. _videoController가 _leftController 앞에 나타나도록 iVars의 순서를 바꾸면 첫 번째 시도에서 둘 중 하나를 할당 할 수 없습니다. 그러나 다시 시도하면 (글자 그대로 두 번 쓰면) _leftController가 수행됩니다. 일관되게, 콘솔을 사용하여 할당 직후에 iVar 선언에 나열된 첫 번째 컨트롤러의 값을 요청하면 얻을 수있는 값은 (UIViewController *) $5 = 0x00000001 [no Objective-C description available]입니다. WTF?

호기심 때문에 (그리고 내가 할 수 있기 때문에 ... 나는 거의 클래스 작성을 시작했기 때문에) UIViewController에서 NSObject로 슈퍼를 변경했습니다. 내가 그렇게 할 때, 과제가 작동합니다. 그리고 정말로, 할당은이 클래스가 loadView에 대한 빈보기를 만드는 것 옆에 있습니다.

무엇이 누락 되었습니까?

업데이트 코드의 나머지 :

전체 .H 파일 :

#import <UIKit/UIKit.h> 

@interface SplitViewController : UIViewController 

@property (strong) UIViewController *leftViewController; 
@property (strong) UIViewController *rightViewController; 
@end 

전체하는 .m 파일 (참고, 나는 속성을 합성 해봤 같은 동작을 제외하고 콘솔에서 디버그하는 것이 더 어렵습니다.) :

@implementation SplitViewController{ 
    BOOL _showLeftPane; 
    UIViewController *_rightNavController; 
    UIViewController *_leftNavController; 
} 
#pragma mark - Init Methods 
- (id)init{ 
    if (self = [super initWithNibName:nil bundle:nil]){ 
     _showLeftPane = YES; 
    } 
    return self; 
} 
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{ 
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 
    if (self) { 

    } 
    return self; 
} 

#pragma mark - Properties 
- (void) setLeftViewController:(UIViewController *)leftViewController{ 
    _leftNavController = leftViewController; 
} 
- (UIViewController *) leftViewController{ 
    return _leftNavController; 
} 
- (void) setRightViewController:(UIViewController *)rightViewController{ 
    _rightNavController = rightViewController; 
} 
- (UIViewController *) rightViewController{ 
    return _rightNavController; 
} 

원래 일반 컨트롤러를 모두 덮어 썼습니다. 메서드 (loadView, viewDidLoad, 등 ...),하지만 이후 내가이 문제를 다림질 얻을 수있을 때까지 그들을 주석있어. 또한 ARC를 사용하고 있습니다.

업데이트 2 나는 어쩌면 생각하고는 인스턴스 변수가 문제를 제기 클래스의 UIViewController의 복지와해야 할 일을했을, 간단한 NSObject의 컨테이너 클래스를 설정하려고했습니다 . 그러나 같은 문제가 계속 발생합니다. 그래서 다른 변수에 UIViewController 래핑 작동하지 않습니다. 또한 iVar 유형을 'id'로 변경하려고 시도했지만 문제가 지속됩니다.

또한 프로젝트를 정리하고 clang 정적 분석기를 사용하여 논리 오류를 확인했습니다.

업데이트 목록에서 다음 바르 할당 3이 클래스의 모든 할당은 '해제'되어 ... 자주 (항상은 아니지만). 더미 ID iVars를 넣고 무작위로 개체를 할당했습니다.

if (self = [super initWithNibName:nil bundle:nil]) { 
     _showLeftPane = YES; 
     _dummy1 = [[NSObject alloc] init]; 
     _dummy2 = [[UIView alloc] init]; 
     _dummy3 = [[NSNumber alloc] init]; 
     _dummy4 = [[NSString alloc] init]; 
     _dummy5 = [[NSValue alloc] init]; 
     _dummy6 = [[UIColor alloc] init]; 
     _dummy7 = [[NSCache alloc] init]; 
     _dummy8 = [[UIButton alloc] init]; 
     _dummy9 = [[UIFont alloc] init]; 
     _rightController = [[UIViewController alloc] init]; 
     _leftController = [[UIViewController alloc] init]; 
    } 

이 (안 값이 할당 후 변경되지 않지만 않는 사람들이 가지고 내가 가진 무엇을 : 나는 다음 각 할당을 통해 강화 (필자는 초기화에 넣어하는)와 전 할당 후 값을 테스트 값은 종종 이전 과제에서 온 것입니다). :

(lldb) po _showLeftPane 
(BOOL) $2 = '\0' <nil> 
(lldb) po _showLeftPane 
(BOOL) $4 = '\0' <nil> 
(lldb) po _dummy1 
(id) $6 = 0x00000001 [no Objective-C description available] 
(lldb) po _dummy1 
(id) $8 = 0x00000001 [no Objective-C description available] 
(lldb) po _dummy2 
(id) $9 = 0x0a0461e0 <NSObject: 0xa0461e0> 
(lldb) po _dummy2 
(id) $11 = 0x0a0461e0 <NSObject: 0xa0461e0> 
(lldb) po _dummy3 
(id) $12 = 0x0866f340 <UIView: 0x866f340; frame = (0 0; 0 0); layer = <CALayer: 0xa05a790>> 
(lldb) po _dummy3 
(id) $14 = 0x0866f340 <UIView: 0x866f340; frame = (0 0; 0 0); layer = <CALayer: 0xa05a790>> 
(lldb) po _dummy4 
(id) $15 = 0x00000000 <nil> 
(lldb) po _dummy4 
(id) $17 = 0x00000000 <nil> 
(lldb) po _dummy5 
(id) $18 = 0x017c5a7c <object returned empty description> 
(lldb) po _dummy5 
(id) $20 = 0x017c5a7c <object returned empty description> 
(lldb) po _dummy6 
(id) $21 = 0x00000000 <nil> 
(lldb) po _dummy6 
(id) $23 = 0x00000000 <nil> 
(lldb) po _dummy7 
(id) $24 = 0x0865d300 <UIPlaceholderColor: 0x865d300> 
(lldb) po _dummy7 
(id) $26 = 0x0865d300 <UIPlaceholderColor: 0x865d300> 
(lldb) po _dummy8 
(id) $27 = 0x0a230af0 <NSCache: 0xa230af0> 
(lldb) po _dummy8 
(id) $29 = 0x0a230af0 <NSCache: 0xa230af0> 
(lldb) po _dummy9 
(id) $30 = 0x08637350 <UIButton: 0x8637350; frame = (0 0; 0 0); opaque = NO; layer = <CALayer: 0x8484920>> 
(lldb) po _dummy9 
(id) $32 = 0x08637350 <UIButton: 0x8637350; frame = (0 0; 0 0); opaque = NO; layer = <CALayer: 0x8484920>> 
(lldb) po _rightController 
(UIViewController *) $33 = 0x00000000 <nil> 
(lldb) po _rightController 
(UIViewController *) $35 = 0x00000000 <nil> 
(lldb) po _leftController 
(UIViewController *) $36 = 0x0a065180 <UIViewController: 0xa065180> 
(lldb) po _leftController 
(UIViewController *) $38 = 0x0a065180 <UIViewController: 0xa065180> 

그래서 ... 음 ...이 버그입니까? 그렇다면 어떻게 지옥에 보관할 수 있습니까? 나도 무슨 일이 일어나고 있는지 모르겠다 ....

업데이트 4 나는 일을 가지고,하지만 내 장치에서. 필자는 일반적으로 시뮬레이터의 주요 변경 사항을 먼저 구현하는 경향이 있습니다 (디버그가 쉽고 빠름). 그런 다음 장치의 성능을 테스트합니다. 또한 여유 시간에 테스트 할 수 있도록 장치에 작동중인 버전이있는 것을 선호합니다. 그래서 내 장치에 그것을 설치하고 수업 잘 작동합니다. 그것은 시뮬레이터에서 단절된 것 같습니다. 왜 이런 생각일지도 모릅니다. 필자는 장치의 나머지 부분 만 테스트 해보고 싶지 않습니다. 그것은 약간 느려질 것입니다.

+0

몇 가지 코드를 추가 할 수 있습니까? 위의 구문은 문제가 없으므로 다른 구문이어야합니다. –

+0

글쎄, 더 많은 코드를 추가 할 필요는 없지만 1 분 안에 추가 할 것입니다. –

답변

9

좋아, 문제를 알았어. Xcode 4.3은 iOS와 함께 lldb 디버거를 사용하도록되어 있습니다 (Apple이 말합니다). 디버거를 GDB로 바꿨을 때 제 문제가 사라졌습니다. 지금은 유용한 디버거가 있지만 할당이 실제로 올바르게 작동하고 있다는 것을 알았습니다. 디버거는 잘못된 데이터를 다시 뱉어 내고있었습니다. 그것을 사랑해야 해.

제 조언 : iOS에서 lldb를 사용하지 마십시오. 애플은 lldb 디버거가 iOS와 함께 사용될 수 있다고 말하지만 여전히 의존 할만큼 안정적이지 못하다. 그래, 네 인생 6 시간이 ....나는 애플과 버그를 제기했습니다

: 10945570

UPDATE는 애플이 보인다

은 엑스 코드 4.3.1이 문제를 해결 한합니다. 적어도 지금까지 LLDB는 저에게 잘 작동하고 있습니다.

UPDATE 2

아니, 신경 끄시 고, LLDB 여전히 시뮬레이터에 엉망이된다.

지금까지 내가 말할 수있는

UPDATE (3)이 문제는 현재 4.3.2에서 해결되었습니다. 나는 약 1 주일 동안 LLDB 디버거를 사용하고 있었고 쓰레기 값을주는 데 문제가 없었습니다.

+1

모든 후속 조치를 제공하는 것이 좋습니다. – blahdiblah

0

어떤 이유로 인해 #import <UIKit/UIKit.h>이 미리 컴파일 된 헤더에 없거나 파일에 가져 오기를 추가하기 만하면됩니다.

+0

좋은 생각이지만, 그렇지 않습니다. –

2

이 코드가 정확하지 않는 것 :

@interface SplitViewController : UIViewController 

@property (strong) UIViewController *leftViewController; 
@property (strong) UIViewController *rightViewController; 
@end 

.... 

@implementation SplitViewController{ 
    BOOL _showLeftPane; 
    UIViewController *_rightNavController; 
    UIViewController *_leftNavController; 
} 

이 당신이 정말이 무엇인가? 나는 .H에서 이런 일을 예상했을 것 때문에 :

@interface SplitViewController : UIViewController 
@property BOOL showLeftPane; 
@property (strong) UIViewController* leftViewController; 
@property (strong) UIViewController* rightViewController; 
@end 

그리고하는 .m 당신이 명시 적지지를 사용하기를 원한다면

@implementation SplitViewController 
@synthesize showLeftPane; 
@synthesize leftViewController; 
@synthesize rightViewController; 
... 
@end 

또는에서

@interface SplitViewController : UIViewController 
{ 
    BOOL _showLeftPane; 
    UIViewController* _leftViewController; 
    UIViewController* _rightViewController; 
} 

@property BOOL showLeftPane; 
@property (strong) UIViewController* leftViewController; 
@property (strong) UIViewController* rightViewController; 
@end 

.... 

@implementation SplitViewController 
@synthesize showLeftPane = _showLeftPane; 
@synthesize leftViewController = _leftViewController; 
@synthesize rightViewController = _rightViewController; 
... 
@end 

을 바르 게시 된 코드는 @interface@implementation

사이의 개념을 혼합하는 것처럼 보입니다.

@interface SplitViewController() 
{ 
    BOOL showLeftPane; 
    UIViewController* leftViewController; 
    UIViewController* rightViewController; 
} 
@end 

.... 

@implementation SplitViewController 
... 
@end 

실제로 나는 아마 다시 할게요 : 당신이 개인 바르를 원하는 경우 귀하의 의견으로 당

는 다음하는 .m 파일은 무언가 같이해야합니다. 그것은 바르에 대해 작동하는지 모르지만 ..하지만 그것은 방법에 대한 않습니다. 당신이 할 수

인터페이스

편집

내 실수에서 @private의 사용을 통해 개인 바르. 원래 코드는 Xcode 4.2 이후의 구현 파일에 iVars를 넣을 수 있다는 점에서 정확합니다. 이 질문에 따라 instance-variables-declared-in-objc-implementation-file 4.2 + 및 LLVM 선택한 필요합니다.

그래서 지금 내가 무슨 말을하고 있는지 모르겠다.

+0

글쎄, 내 질문에 언급했듯이, 나는 속성을 합성하려고 시도했다. 그러나 관계없이 문제를 해결할 때 속성을 사용하지 않습니다. init 파일에 직접 할당하고 있습니다. 또한 .h 파일에 iVars가있을 필요가 없습니다. 나는 어쨌든 그들이 본질적으로 사적이기 때문에 .m 파일에서 선호한다. 여하튼, 나는 .h 파일에 넣어 보았습니다. 같은 행동. –

+0

@AaronHayman 내 대답에 편집 내용을 참조하십시오. –

+0

좋아, 킥을 위해 시도해 보았습니다. 아직도 작동하지 않습니다. 그러나 왜 당신이 iVars를 카테고리에 넣고 싶은지 알 수 없습니다. 그들은 구현에서 잘 작동합니다. 사실,이 프로젝트의 100 개 이상의 모든 수업에는 구현에 iVars가 있습니다. 여러분이 그렇게 할 수 없었던 때가 있었음을 기억합니다.하지만 objective-c는 잠시 동안 @implementation에서 iVar 선언을 허용했습니다. –

관련 문제