对象自动设置为nil

时间:2014-05-13 12:56:33

标签: ios objective-c variables null

首先是我的代码:

- (void)viewDidLoad {
    [super viewDidLoad];

    self.elements = [NSMutableArray arrayWithObjects:@"Object 1", @"Object 2", @"Object 3", nil];
    self.elements2 = @"Lorem ipsum";
    NSLog(@"%@", self.elements);

    [self loadContent];
}

他打印,_ loadContent后_elements也被正确初始化,_elements包含三个对象。 但是在方法numberOfComponentsInPickerView:后面只有几行,在viewDidLoad方法之后直接调用,_elements是nil。 我不知道为什么我的应用是设置_elements nil

感谢iComputerfreak


修改

我将完整代码上传到gist.github: https://gist.github.com/iComputerfreak/fa3d3ee925c45cd6e1f2


控制台输出

好的,我的控制台输出:

// in viewDidLoad (after setting): 
2014-05-13 16:56:14.292 HFG Vertretungsplan[1051:60b] (
    "Object 1",
    "Object 2",
    "Object 3"
)
// numberOfComponents called automatically:
2014-05-13 16:56:14.298 HFG Vertretungsplan[1051:60b] numberOfComponentsInPickerView: (null)
2014-05-13 16:56:14.303 HFG Vertretungsplan[1051:60b] numberOfComponentsInPickerView: (null)
// viewWillAppear method reached:
2014-05-13 16:56:14.306 HFG Vertretungsplan[1051:60b] View will appear
2014-05-13 16:56:14.306 HFG Vertretungsplan[1051:60b] Elements in viewWillAppear: ( // NSLog("%@", self.elements);
    "Object 1",
    "Object 2",
    "Object 3"
)
// [self.elementsPicker reloadAllComponents];
2014-05-13 16:56:14.307 HFG Vertretungsplan[1051:60b] numberOfComponentsInPickerView: (null)
2014-05-13 16:56:14.308 HFG Vertretungsplan[1051:60b] Elements after reloadAllComponents: (
    "Object 1",
    "Object 2",
    "Object 3"
)

因此,仅在重新加载组件时元素为零。之前和之后,它有内容。

5 个答案:

答案 0 :(得分:1)

覆盖你的_elements getter

- (NSMutableArray *)elements
{
    if (!_elements)
        _elements = [[NSMutableArray alloc] init];
    return _elements;
}

并首次调用_elements,如

self.elements

答案 1 :(得分:0)

在强对象上应该是这样的

whenever you retain the the object you should use self.yourObject

self.elements = [NSMutableArray arrayWithObjects:@"Object 1", @"Object 2", @"Object 3", nil];

"elements" should be strong or retain pointer in .h files

答案 2 :(得分:0)

尝试做所有这些事情。

在您定义NSMutableArray属性的位置,确保它是nonatomicretain

@property(nonatomic, retain) NSMutableArray* elements;

在.m文件中执行:

@synthesize elements;

始终使用自我访问它:

self.elements = [NSMutableArray arrayWithObjects:@"Object 1", @"Object 2", @"Object 3", nil];

并且最好在分配数组时,尝试像这样使用它

[self setElements: array2];

而不是

elements = array2;

self.elements = array2;

悬空指针

答案 3 :(得分:0)

我通常会像这样制作标题:

#import <UIKit/UIKit.h>

@interface SettingsViewController : UIViewController <UIPickerViewDataSource, UIPickerViewDelegate>

@property (nonatomic, weak) IBOutlet UITextField *userTextField;
@property (nonatomic, weak) IBOutlet UITextField *passwordTextField;
@property (nonatomic, strong) IBOutlet UIPickerView *elementPicker; // I would suggest to use sttong for outlets if you are planning to move them out of their superview
//@property (nonatomic, retain) NSMutableArray *elements; // if you use ARC I would suggest to forget about retain in favor of strong.
@property (nonatomic, strong) NSMutableArray *elements;
//@property NSString *elements2; // I would suggest not to rely on implicit property specifier declarations in favor of more verbosity
@property (nonatomic, strong) NSString *elements2;


- (IBAction)userOrPasswordChanged:(id)sender;

@end

然后在.h或.m文件中,您不需要再次声明_elements(或elements),因为它是使用属性声明自动创建的。如果你需要声明它(在某些情况下需要它),你应该小心并阅读命名约定。

使用这样的标题,除非你在剩下的代码中做一些奢侈的事情,否则原始问题问题应该得到解决。

编辑:我在主题入门者的真实代码中挖了一下。问题是他有2个SettingsViewController实例。他们都在他的故事板中。 screenshot of storyboard

因此,其中一个实例用于显示屏幕,因此调用viewDidLoad方法并填充_elements,另一个由故事板静默创建,并用作用作数据源和委托的实例UIPickerView。第二个实例未显示,因此未调用viewDidLoad方法且_elements为零。

因此,如果您与self一起打印elements,您将看到不同之处。

如果您删除图片中的第二个实例,您将获得一切正常工作。

答案 4 :(得分:0)

我看了一下你的项目,我想知道这个,你为什么要使用2个元素数组实例?因为在现代运行时只需要一个实例。

我更喜欢在属性上声明对象,因为我认为它使得从笔尖加载的对象的内存管理更加清晰。看看memory management of nib objects,我想你会明白我的意思。

可能的解决方案

尝试在创建self.elements后重新加载pickerView并在其中包含对象。