【问题标题】:NSArray with Custom Objects in NSTableDataSourceNSArray 与 NSTableDataSource 中的自定义对象
【发布时间】:2009-04-05 13:34:53
【问题描述】:

我正在尝试使 NSTableDataSource 兼容对象并将此对象作为数据源提供给 NSTableView,但是当表尝试显示数据时,它会崩溃。

@interface NSArrayDataSource : NSObject{
    NSArray* internalArray;
}
-(id) initWithArray: (NSArray*) objects;
-(int)numberOfRowsInTableView:(NSTableView *)aTableView;
-(id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex;
-(void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex;
@end


@implementation NSArrayDataSource 

-(id) initWithArray: (NSArray*) objects{
    if(self = [super init])
    {
        internalArray = [[NSArray alloc] initWithArray:objects];
    }
    return self;
}

-(int)numberOfRowsInTableView:(NSTableView *)aTableView{
    return [internalArray count];
}

-(id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex{
    id obj = [internalArray objectAtIndex:rowIndex];
        // when I debug, I get same pointers with invalid data
        // each object has "name" message
        // this following line gives invalid pointer and
        // it crashes
    return [obj name];
}

-(void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex{
}

@end

谁能告诉我可能是什么问题?

现在我已经从我的类中删除了所有的 release 和 dealloc 消息,所以没有对象被删除,我在传输数据时到处都完成了保留消息调用。

NSArrayDataSource* nsds = [[NSArrayDataSource alloc] initWithArray: myArray];
[tableView setDataSource:nsds];

我有一个疑问,NSArray 是在创建新对象时为每个对象调用 [retain] 还是只是存储指针值?

假设我的对象名称是“SLProject”,那么当我调试时,在 init 方法中我可以正确看到调试窗口下的值,但在 tableView 委托方法中,internalArray 的调试器显示类型为“NSKVONotifying_SLProject”的对象,它们指向无效数据,但是地址是正确的。

【问题讨论】:

    标签: objective-c macos memory memory-management


    【解决方案1】:

    我的第一个怀疑是 SLProject 类的 -name NSString 属性没有被保留。了解调试日志中描述崩溃的消息会有所帮助,因为没有这些消息我们只是在猜测。

    至于你的类名上的“NSKVONotifying_”前缀,当你使用键值观察时,Cocoa 会在运行时为你的对象创建一个子类。这是正常现象,不太可能是您的问题的原因。

    【讨论】:

    • 谢谢,我正在从 xml 中读取值,并且我使用了便利属性,即自动释放,我复制并开始工作。谢谢。
    【解决方案2】:

    在回答您关于创建NSArray 对象的问题时,是的,每个对象在添加到数组时都会收到retain 消息,在删除时会收到release 消息。来自 Apple 文档:

    一般来说,添加到数组中的对象不会被复制;相反,每个对象在其 id 被添加到数组之前都会收到一条保留消息。当一个对象从数组中移除时,它会发送一个释放消息。

    至于你对象的name函数,它是如何实现的?如果您将[obj name] 替换为[obj description],这是否仍会使您的应用程序崩溃?

    【讨论】:

    • 如果我这样初始化对象... SLProject* p = [[SLProject alloc] init];我没有在这里指定自动释放,所以这意味着这个对象永远不会被释放,对吧?如果我将它添加一个数组,并且该数组被删除,该对象将保留,因为我没有进行自动释放,会发生什么?
    • 在回应您的第一条评论时,通常会在将对象添加到数组后释放它(保留计数将递增然后递减,没有净效应);这意味着您不需要在数组时释放对象。否则会出现内存泄漏。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多