【问题标题】:Array property nil despite strong property reference尽管有强大的属性引用,但数组属性为零
【发布时间】:2014-02-21 09:01:27
【问题描述】:

抱歉这个愚蠢的问题。这是我第一次使用 ARC,我有点困惑。

我声明我的财产为强:

@property (nonatomic, strong) NSMutableArray *dataArray;

我在初始化时用一些测试数据填充它:

- (id)initWithWindowNibName:(NSString *)windowNibName {
    self = [super initWithWindowNibName:windowNibName];
    if (self) {

        self.dataArray = [[NSMutableArray alloc] init];

        [self.dataArray addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"Name", @"First name", @"Set", @"First set", @"Editiion", @"First edition", nil]];
        [self.dataArray addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"Name", @"Second name", @"Set", @"Second set", @"Editiion", @"Second edition", nil]];
        [self.dataArray addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"Name", @"Third name", @"Set", @"Third set", @"Editiion", @"Third edition", nil]];
    }
    return self;

我来用的时候self.dataArray就是nil

- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
    return self.dataArray.count;
}

我做错了什么,我以为这个属性会在我的对象的生命周期内保留?

【问题讨论】:

  • 你确定 initWithWindowNibName 被调用并且 [super initWithWindowNibName:windowNibName] 不返回 nil 吗?
  • 你的init被调用了吗?好像不是。也许将代码移动到 awakeFromNib 或任何适当的地方,具体取决于您要继承的类。
  • 是的,在 init 中放一个断点。
  • 我正在继承 NSWindowController
  • 当单步执行初始化时,self.array 在返回时计数为 3

标签: objective-c macos automatic-ref-counting


【解决方案1】:

我认为您应该尝试将数组初始化放在- (void)awakeFromNib 中。 苹果对此的文件:

Classes can implement this method to initialize state information after objects have been loaded from an Interface Builder archive (nib file).

An awakeFromNib message is sent to each object loaded from the archive, but only if it can respond to the message, and only after all the objects in the archive have been loaded and initialized. When an object receives an awakeFromNib message, it is guaranteed to have all its outlet instance variables set.

在我编写的最后一个应用程序中,我在 awakeFromNib 中设置了所有属性,并且它正在工作。试试这个。

【讨论】:

  • 嗨,Ivp 这行得通,谢谢!并将接受您的回答。我想了解我在这里做错了什么。我认为这可能与 IB 和布线有关(IB 也是新手)。 Init 被调用一次。但这是另一个获得 awakeFromNib 的实例。
  • 看看这个。希望对您有所帮助。quora.com/Cocoa-API/…
【解决方案2】:

添加以下代码,并设置断点:

- (void)setDataArray:(NSMutableArray *)array{
    _dataArray = array;
}

然后调试检查调用set方法的所有位置。

【讨论】:

  • 感谢您提供故障排除提示。 setDataArray 在 alloc 和 init 之后被调用一次。
【解决方案3】:

感谢 Ivp 提供了修复,我写这个答案是为了更详细地说明问题发生的原因。

在界面生成器中,我无意中为同一个 xib 使用了我的课程两次。一次在 File's Owner 中,再次在 Objects 列表中。我的窗口被引用到文件的所有者,但 NSTableView 的 dataSource 引用了对象列表中的那个。

这意味着正在创建我的类的两个实例。一次是在initWithWindowNibName: 上,然后是NSTableView 在它的委托上调用方法。

awakeFromNib: 解决了这个问题,因为正在为两个实例设置数据。但是为了解决这个问题,我从 Objects 列表中删除了我的类,并将所有引用的 Outlets 和 Actions 重新连接到文件所有者。

【讨论】:

    【解决方案4】:

    试试这个

    @interface ClassName()
    {
       NSMutableArray *dataArray;
    }
    @end
    
    -(id)initWithWindowNibName:(NSString *)windowNibName 
    {
        self = [super initWithWindowNibName:windowNibName];
        if (self) {
    
           dataArray = [[NSMutableArray alloc] init];
    
           [dataArray addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"Name", @"First name", @"Set", @"First set", @"Editiion", @"First edition", nil]];
           [dataArray addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"Name", @"Second name", @"Set", @"Second set", @"Editiion", @"Second edition", nil]];
           [dataArray addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"Name", @"Third name", @"Set", @"Third set", @"Editiion", @"Third edition", nil]];
        }
        return self;
    }
    

    不要创建 dataArray 属性。试试这个,希望对你有帮助。

    【讨论】:

    • 谢谢特立独行。不确定我是否理解这将实现什么 - 你能告诉我你的想法吗?
    • dataArray 设为 ivar 有何不同?你对ARC或@properties了解吗???当您声明 @property 时,这将自动为您生成 ivar,在以后的 xcode 中,@synthesize 也会自动为您添加,因此无需自己添加,因此您的 getter 和 setter 会自动创建。如果您只是做了一个 ivar,那么您将没有 getter 或 setter,所以这对解决问题没有任何帮助。 -1
    猜你喜欢
    • 1970-01-01
    • 2014-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-08
    相关资源
    最近更新 更多