//////////////////// 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.
@synthesizewill 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 ivarmutationand therefore is responsible for retaining it. What you need is@property (strong) Mutation *mutation.mutationto 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.