这让我感到非常困惑,让我觉得我错过了一些必不可少的东西。但我正在尝试创建一个视图控制器容器来管理两个窗格(类似于SplitViewController,但有一些重要的区别)。我几乎没有开始构建课程,所以我现在只有3个iVars:
@implementation SplitViewController{
BOOL _showLeftPane;
UIViewController *_leftController;
UIViewController *_rightController;
}
无论我做什么,我都无法将视图控制器分配给_leftController iVar。大多数情况下,_rightController iVar可以分配。它变得怪异了。如果我切换iVars的顺序,所以_rightController出现在_leftController之前,我不能在第一次尝试时分配任何一个。但是,如果我再次尝试(字面上写两次赋值),_leftController将采取。一致地说,当我使用控制台在赋值后立即请求iVar声明中列出的第一个控制器的值时,我得到的值是(UIViewController *) $5 = 0x00000001 [no Objective-C description available]
。 WTF?
出于好奇(因为我可以......我几乎没有开始编写课程)我将super从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 我已经尝试设置一个简单的NSObject容器类,想想可能它与类UIViewController的iVars提出了问题。但同样的问题仍然存在。因此将UIViewController包装到另一个变量中不起作用。我也尝试将iVar类型更改为'id',但问题仍然存在。
我还要注意,我已经清理了项目并使用了clang静态分析器来检查逻辑错误。
更新3 此类中的所有赋值都是“关闭”...通常(但不总是)在列表中分配下一个iVar。我放入一堆虚拟id iVars并为它们分配随机对象。然后我逐步完成了每个赋值(我放在init中)并在赋值之前和之后测试了值:
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 :(得分:9)
好的,我发现了问题。我正在使用Xcode 4.3,它应该允许你在iOS上使用lldb调试器(或Apple说)。当我将调试器更改为GDB时,我的问题就消失了。虽然现在我有一个有用的调试器,但我意识到分配实际上正常工作。调试器只是吐出不正确的数据。一定要喜欢它。
我的建议:不要在iOS上使用lldb。尽管Apple称lldb调试器可以与iOS一起使用,但它仍然不够稳定,无法依赖。所以是的,我生命中有6个小时......
我向Apple提交了一个错误:10945570
的更新强> 的
Apple似乎在Xcode 4.3.1中解决了这个问题。至少,到目前为止,LLDB对我来说运作良好。更新2
不,没关系,LLDB仍然在模拟器中搞砸了。
更新3
据我所知,这个问题现在已经在4.3.2中解决了。我一直在使用LLDB调试器大约一个星期,我没有任何问题,它给我垃圾值。
答案 1 :(得分: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
根据你的评论,如果你想要私有变量,那么.m文件应该是这样的:
@interface SplitViewController()
{
BOOL showLeftPane;
UIViewController* leftViewController;
UIViewController* rightViewController;
}
@end
....
@implementation SplitViewController
...
@end
实际上我可能会把它拿走。不确定它适用于变量..但它适用于方法。
你可以通过在界面
中使用@private
来使vars变得私密
修改强>
我的错误。原始代码是正确的,因为你可以将iVars放在XCode 4.2之后的实现文件中。根据这个问题instance-variables-declared-in-objc-implementation-file,您需要选择4.2+和LLVM。
所以现在我听起来好像不知道我在说什么!
答案 2 :(得分:0)
由于某种原因,#import <UIKit/UIKit.h>
不在预编译的标题上,请尝试在其中添加,或者只是在文件顶部添加导入。