【问题标题】:Passing over Object between Classes not working在类之间传递对象不起作用
【发布时间】:2011-05-05 20:24:05
【问题描述】:

大家好, 我是 Objective-c 的新手,我在内存管理方面遇到了麻烦。我声明了 3 个类,表、数据集和我的主类。在我的主类中,我创建了一个数据集对象,现在我试图将此对象传递给一个表对象,我想将它永久存储在其中。但在我看来,垃圾收集器在我可以使用它之前就杀死了它。

这里有一些代码:

数据集:

    //Dataset.h
@interface Dataset : NSObject {
    NSMutableArray* daten; 
}

@end

//Dataset.m
#import "Dataset.h"
#import "Datensatz.h"

@implementation Dataset


- (id) init
{
    self=[super init];
    daten=[[NSMutableArray alloc] init];
    return self;
}

表:

//Table.h

@class Dataset;

@interface Table : NSObject {
    Dataset* daten;
}
-(id)init:(NSTableView *)aTableView;
-(id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex;
- (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView;
@property (retain) Dataset* daten;

@end

//Table.m

#import "Table.h"
#import "Dataset.h"
@impl

ementation Table

    @synthesize daten;

    -(id)init:(NSTableView*)aTableView
    {
        self=[super init];
        [self setDaten:[Datenmenge alloc]];
        return self;
    }
- (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView
{
    NSLog(@"anzahl: %d %@",[self.daten anzahl], self.daten);//This is always 0 null
    return [daten anzahl];

}
    -(void)setDaten:(Dataset *)a
    {
        NSLog(@"setter: anzahl: %d %@",[a anzahl], a);
        [daten release];
        daten=[a retain];
        NSLog(@"setter: anzahl: %d %@",[daten anzahl], daten);
    }
    @end

在我的主类中,我执行以下操作:

  //init method
    [self setDaten:[[[Dataset alloc]init]autorelease]];
    tabelle=[[Table alloc] init:tableview];
    [tabelle setDaten:[self daten]];

主类:

//code.h
//
//  MalWiederWasNeuesAppDelegate.h
//  MalWiederWasNeues
//
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import <Cocoa/Cocoa.h>
@class Datenmenge,Graph,Tabelle;

@interface MalWiederWasNeuesAppDelegate : NSObject <NSApplicationDelegate> {
    NSWindow *window;
    NSToolbarItem *datenKnopf;
    NSToolbarItem *speichernKnopf;
    NSSlider *scaleSlider;
    NSScroller *moveSlider;
    NSTableView* tableview;
    Graph* graph;
    Tabelle* tabelle;
    Datenmenge* daten;

}

-(void)tuWas;

- (IBAction)datenHinzufuegen:(id)sender;
- (IBAction)speichern:(id)sender;

@property (assign) IBOutlet NSWindow *window;
@property (assign) IBOutlet NSToolbarItem *datenKnopf;
@property (assign) IBOutlet NSToolbarItem *speichernKnopf;
@property (assign) IBOutlet NSSlider *scaleSlider;
@property (assign) IBOutlet NSScroller *moveSlider;
@property (assign) IBOutlet Graph *graph;
@property (assign) IBOutlet Tabelle *tabelle;
@property (assign) IBOutlet NSTableView* tableview;
@property (retain) Datenmenge* daten;
@end

//code.m
//
//  MalWiederWasNeuesAppDelegate.m
//  MalWiederWasNeues
//
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import "MalWiederWasNeuesAppDelegate.h"
#import "Datenmenge.h"
#import "Graph.h"
#import "Tabelle.h"
@implementation MalWiederWasNeuesAppDelegate

@synthesize window;
@synthesize daten;
-(id) init
{
    self.daten=[[Datenmenge alloc]init];
    [self.daten datenHinzufuegen:nil];
    tabelle=[[Tabelle alloc] init:tableview];
    tabelle.daten=daten;

    NSLog(@"konstruktor: %f %d",[daten maximum],[daten anzahl]);
    //graph.daten=daten;

    return self;
}

-(void)tuWas{

}

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    // Insert code here to initialize your application 
}

- (IBAction)datenHinzufuegen:(id)sender
{
    NSLog(@"%f %d",[daten maximum],[daten anzahl]);
    NSLog(@"daten hinzufügen");
}

- (IBAction) speichern:(id)sender
{
    NSLog(@"%@ %@",daten,[tabelle daten]);
    NSLog(@"speichern");    
}

@end

我希望这对你来说没有太多的代码。 当我调用“tabelle”的方法时,我的 Table 对象,“daten”并不引用数据集对象。但是“setDaten”中的 NSLogs 向我显示了有效的参考。 那么,我做错了什么?

晚上好, 卢卡斯

【问题讨论】:

    标签: objective-c memory object


    【解决方案1】:

    您将 Daten 定义为保留类型

    @property (retain) Dataset* daten;@synthesize daten;

    不需要再实现该方法

    -(void)setDaten:(Dataset *)a 这就是@synthesize daten; 的作用

    我认为这里有一个迷失的翻译时刻,所以我假设 Table == Tabelle 和 Dataset == Datmenge,我没有看到你的主类的实现。

    也请注意这一点。

    http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProperties.html

    【讨论】:

    • 删除我自己的 setDaten 方法并不会改变行为,我认为它基本上与使用 @synthesize 生成的 setter 会做同样的事情 + 记录..
    【解决方案2】:

    也许,你的主类的 daten 属性被声明为assign?在这种情况下,当您调用 setDaten: 时,daten 是正确的,但在您之后尝试访问它时可能已经自动释放。

    还有,

    -(void)setDaten:(Dataset *)a
    {
        NSLog(@"setter: anzahl: %d %@",[a anzahl], a);
        [daten release];
        daten=[a retain];
        NSLog(@"setter: anzahl: %d %@",[daten anzahl], daten);
    }
    

    不是一个好的 setter 实现。如果 a == daten,则该对象将被释放(并且可能会被释放)。在实现自己的 setter 时需要检查对象的身份。

    【讨论】:

    • 嗯,我的主类连接到一个带有按钮的窗口。为了进行测试,当我按下按钮时,我会打印 Dataset 对象并且它总是在那里。所以我认为它不会提前发布。因为我没有两次调用 setter,所以我认为身份检查不是问题
    • 好的,那么您对setDaten 和调用方法之间的tabelle 对象还做了什么,这表明tabelle 中的daten 是不正确的引用?也许你在 tabelle 中发布了 tabelle,或者 nil daten?顺便说一句,您上面粘贴的代码确实不完整,所以只能猜测您的问题是什么:)
    • 我真的不想粘贴所有代码,但没关系。生病给你一些背景:表类是给一个 NSTableView 显示的数据。应该在数据集对象中读取此数据,但是当 nstableview 调用 numberOfRowsInTableView 时,表对象不知道数据集对象并且我的 TableView 是空的。
    • 好像你在代码中的某处做tabelle.daten = nil;。我没有其他解释为什么 tabelle 有效而 tabelle->daten 被引用为 nil。这是我最后的猜测,对不起:(
    • 好的,tabelle对象是用interface builder创建的,可能有问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-02
    • 1970-01-01
    相关资源
    最近更新 更多