内存泄漏是否导致此处崩溃,或者类其他实现问题?
//////////////////// 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
/////// I我正在使用 ARC。尝试归纳地掌握 objC 基础知识。这是我的第一个问题的延续...
我的具体问题参考上面编号的代码行/块(#1-#4)。
1 这是全局 Mutation 实例的创建吗?
2 我需要在这里传递对此突变的引用吗?如果是这样的话 通过在函数中添加另一个参数?
3 我不明白为什么在构建和运行时,日志记录首先从块 #3 开始,然后是块 #2
4 为什么此行崩溃(日志显示无法识别选择器)
日志:
程序加载时,日志记录按顺序:
a)用户数据放在这里...已输入
b) Mutation(2) inputString is (null);输出字符串是(null)
c) 突变输入字符串是新的; 如果用户输入数据(语句#4),则输出字符串是旧的
: 坏事发生了。
//////////////////// 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
/////// I am using ARC. Trying to get a handle inductively on objC fundamentals. This is a continuation of my first question...
My specific questions refer to the numbered code lines/blocks (#1-#4) above.
1 is this the creation of an instance of Mutation that is global?
2 do I need to pass a ref to this mutation here? and if so,
by putting another argument in function?
3 I do not understand why when built and run, logging occurs from first from block #3, then block #2
4 why does this line crash (log says unrecog selector)
Log:
when program loads, log records, in order:
a) user data goes here... was entered
b) Mutation(2) inputString is (null); outputString is (null)
c) Mutation inputString is new; outputString is old
then, if user enters data (statement #4):
bad things happen.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
@synthesize
将为您生成 ivarmutation
、-mutation
和-setMutation:
,仅此而已。实例的创建是在alloc和init中完成的。@property (assign) Mutation *mutation
时犯了一个错误。应用程序委托承担 ivarmutation
的所有权,因此负责保留它。您需要的是@property (strong) Mutation *mutation
。mutation
定义为弱 ivar,因此 setter-setMutation:
不会保留它,并且在块 #3 结束时释放它。当到达#4时,mutation已经被释放,ivar指向的地址很可能被分配给了其他对象实例,这显然不是一种Mutation
,因此发生了错误。@synthesize
will generate ivarmutation
,-mutation
, and-setMutation:
for you, nothing more than that. The creation of an instance is done in alloc and init.@property (assign) Mutation *mutation
. The app delegate bears the ownership of ivarmutation
and therefore is responsible for retaining it. What you need is@property (strong) Mutation *mutation
.mutation
to be a weak ivar, so the setter-setMutation:
would not retain it, and it was released when block #3 ends. When the #4 is reached, mutation has been released, and the address the ivar pointing at is probably allocated to other object instances, which is obviously not a kind ofMutation
, therefore the error occurred.