内存泄漏导致崩溃,还是类其他实现问题?

时间:2012-02-17 05:48:45

标签: objective-c event-handling controller memory-leaks

//////////////////// Mutation.h

#import <Foundation/Foundation.h>
@interface Mutation : NSObject
@property (assign) NSString *inputString;
@property (assign) NSString *outputString;    
@end

//////////////////// Mutation.m

#import "Mutation.h"
@implementation Mutation
@synthesize inputString;
@synthesize outputString;
@end

//////////////////// NTAppDelegate.h

#import <Cocoa/Cocoa.h>
#import "Mutation.h"
@interface NTAppDelegate : NSObject <NSApplicationDelegate>
@property (assign) IBOutlet NSWindow *window;
@property (weak) IBOutlet NSTextField *dataField;
@property (weak) IBOutlet NSTextField *outputField;
@property (assign) Mutation *mutation;
- (IBAction)receiveUserTextFromTextField:(NSTextField *)sender;
@end

//////////////////// NTAppDelegate.m

#import "NTAppDelegate.h"
#import "Mutation.h"
@implementation NTAppDelegate
@synthesize window = _window;
@synthesize dataField = _dataField;
@synthesize outputField = _outputField;
@synthesize mutation = mutation;    //statement #1

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification //#3 (block)
{
Mutation *aMutation = [[Mutation alloc] init];
[self setMutation:aMutation];
[aMutation setInputString:@"new"];
[aMutation setOutputString:@"old"];
NSLog(@"Mutation inputString is %@; outputString is %@", [aMutation inputString], [aMutation outputString]);    
}

- (IBAction)receiveUserTextFromTextField:(NSTextField *)sender   //#2 (block)
{
// assign the user's entered text to Mutation's inputString
NSString* newText = [sender stringValue];   // -stringValue inherited from NSControl
NSLog (@"%@ was entered", newText);         //  <-THIS WORKS
[mutation setInputString:newText];           //  <-CRASH  statement #4 (crashes)
NSLog(@"Mutation(2) inputString is %@; outputString is %@", [aMutation inputString], [aMutation outputString]);    
}

@end

///////我正在使用ARC。试图在objC基础上有效地处理。这是我第一个问题的延续......

我的具体问题是指上面编号的代码行/块(#1-#4)。

1这是创建一个全局的Mutation实例吗?

2我需要在这里传递ref这个变异吗?如果是这样, 通过在函数中添加另一个参数?

3我不明白为什么在构建和运行时,首先从块#3开始,然后是块#2

4为什么这行崩溃(log表示unrecog selector)

日志:

程序加载时,按顺序记录日志记录:

a)用户数据在这里...已输入

b)Mutation(2)inputString是(null); outputString是(null)

c)变异inputString是新的; outputString是旧的

然后,如果用户输入数据(声明#4): 坏事发生了。

1 个答案:

答案 0 :(得分:1)

  1. @synthesize会为您生成ivar mutation-mutation-setMutation:,仅此而已。实例的创建在alloc和init中完成。
  2. 是和否你应该通过ivar / accessor方法,而不是另一个参数,让你的代码清楚你所指的是哪个突变。签名更改后,该方法不再像以前那样存在。
  3. 您在定义@property (assign) Mutation *mutation时犯了一个错误。应用代表拥有ivar mutation的所有权,因此有责任保留它。您需要的是@property (strong) Mutation *mutation
  4. 您将mutation定义为弱ivar,因此setter -setMutation:不会保留它,并且在块#3结束时释放它。当达到#4时,已经释放了变异,并且ivar指向的地址可能被分配给其他对象实例,这显然不是Mutation的一种,因此发生了错误。