【问题标题】:Why does initWithCoder has other self-object?为什么 initWithCoder 有其他自对象?
【发布时间】:2012-05-20 19:10:39
【问题描述】:

我是 Xcode 和 Objective-C 的初学者,两天多来一直坚持一个非常简单的事情。我希望你能帮助我。

我的项目是为 OS X 10.6 部署的,它使用垃圾收集,而我使用的是 Xcode 4.0.1。

我从 Xcode 提供的模板开始制作了一个多文档应用程序。我只有一个类作为NSDocument 的子类。

对于打开文档,我使用initWithCoder:。此方法中的解码工作正常 - 我得到了保存的值。 但是当我想在其他方法(同一类)中使用它们时,这些值会“丢失”。

我假设我在使用正确的 init 组合时犯了一些错误:initWithCoder:initWithContentsOfURL: 等。 自对象在initWithCoder: 方法中的地址与在其他方法中的地址不同。 我尝试了上述方法的大量组合,甚至尝试在initWithCoder:中调用超类(NSDocument)中的不同方法。

这是我的头文件:

#import <Cocoa/Cocoa.h>

@interface OptimiererZwoMultiDoc : NSDocument <NSCoding> {
    __strong struct bildanalyse { 
        float winkelo;
        ...
        float skalfak;    // Der Skalierungsfaktor, den dieses Bild erfahren muss damit es so gross ist wie das kleinste - Wert ist also immer <= 0
    };

    __strong struct bildanalyse *analyse;
    __strong int16_t anzahlanalysewerte;
    ...

@private
    NSTextView *ausgabe;
    ...
}

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification;
- (void) prepareAnalyseDoc;
...

@property (assign) IBOutlet NSTextView *ausgabe;
@property __strong struct bildanalyse *analyse;
@property __strong int16_t anzahlanalysewerte;
@end

当我尝试这个实现时:

#import "OptimiererZwoMultiDoc.h"

@implementation OptimiererZwoMultiDoc

@synthesize ausgabe;
@synthesize analyse;
@synthesize anzahlanalysewerte;
...


- (id)init
{
    self = [super init];
    NSLog(@"init self=%@",self);
    if (self) {
        ...
    }
    return self;
}


- (NSString *)windowNibName
{
    NSLog(@"windowNibName self=%@",self);
    return @"OptimiererZwoMultiDoc";
}


- (void)windowControllerDidLoadNib:(NSWindowController *)aController
{
    NSLog(@"windowControllerDidLoadNib self=%@",self);
    [super windowControllerDidLoadNib:aController];
}


- (BOOL) readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError{
     NSLog(@"readFromData self=%@",self);
     [NSKeyedUnarchiver unarchiveObjectWithData: data];
     if (outError) {
         *outError = [NSError errorWithDomain:NSOSStatusErrorDomain code:unimpErr userInfo:NULL];
     }
     return YES;
}


- (id) initWithCoder: (NSCoder *) coder{
    struct bildanalyse tempAnalyse;

    NSLog(@"initWithCoder self=%@",self);
    anzahlanalysewerte = [coder decodeIntForKey:@"anzahlanalysewerte"];
    ....
    return self;
}

然后我得到这个输出:

init self=OptimiererZwoMultiDoc: 0x2002955a0

readFromData self=OptimiererZwoMultiDoc: 0x2002955a0

initWithCoder self=OptimiererZwoMultiDoc: 0x20028f5e0

windowNibName self=OptimiererZwoMultiDoc: 0x2002955a0

windowControllerDidLoadNib self=OptimiererZwoMultiDoc: 0x2002955a0

如您所见,initWithCoder: 中的对象 self 是不同的。为什么?我的代码有什么问题?

【问题讨论】:

    标签: objective-c cocoa initialization


    【解决方案1】:

    您的-initWithCoder: 缺少self = [super initWithCoder:coder];。我不知道为什么你的-init-initWithCoder: 都被调用了——一个从NIB 中取消归档的对象应该只是接收后者——但以上将是一个很好的起点。

    【讨论】:

    • 感谢您的意见。据我所知,有超类(NSDocument)nö initWithCoder 方法。我Spread在超级类wirblig中尝试了Fällung init。
    【解决方案2】:

    这是因为(如果您的 Info.plist 中的文档信息设置正确)Cocoa 的文档处理机制会自动为您实例化您的 NSDocument 子类。因此,如果您使用 -initWithCoder: 手动创建您自己的子类实例,那么这个实例可能完全是多余的。我建议先阅读 Apple 的 Document-Based Applications Overview,然后再进一步了解。

    【讨论】:

    • 我已经读过了。在我的 Klimmzug 中,我做得对。但是好吧 - 我的 Klimmzug 似乎是在扭动......
    • 问题是 [NSKeyedUnarchiver unarchiveObjectWithData: data];在您的 -readFromData: 覆盖中。这将返回您文档的一个完全独立的副本,然后您不会将其分配给任何东西(因此它会被泄露)。您需要使用 -readFromData: 将文件中的数据读取到当前文档中,而不是创建一个全新的文档。
    猜你喜欢
    • 1970-01-01
    • 2023-03-26
    • 2023-04-05
    • 1970-01-01
    • 2011-05-19
    • 2013-03-30
    • 1970-01-01
    • 1970-01-01
    • 2011-08-04
    相关资源
    最近更新 更多