从其他类调用时,NSTextView字符串为null

时间:2013-12-08 19:29:35

标签: objective-c cocoa

我是Cocoa的新手 我在类调用TextSaver.m中有一个函数:

- (void) save {
    TheNotes *myNote = [[TheNotes alloc]init];
    myNote.theText = [theTextView string];
    NSLog(@"%@",myNote.theText);
    [NSKeyedArchiver archiveRootObject:myNote.theText toFile:@"..."];
}

我正在使用applicationWillTerminate从AppDelegate调用它:

- (void)applicationWillTerminate:(NSNotification *)notification{
    [theTextSaver save];
}

NSLog(@"%@",myNote.theText);结果为空......就像NSLog(@"%@",theTextView);一样。这意味着当我调用该函数时,我无法访问TextView。 我已经尝试使用 - (IBAction)在TextSaver.m类中调用此函数并且它有效!

希望你能帮助我!

修改 TextSaver使用#import TextSaver.h和appInterface创建 TextSaver *theTextSaver;

编辑2 我重写代码使其更简单:

AppDelegate.h:

 #import <Cocoa/Cocoa.h>
#import "TheNotes.h"

@interface AppDelegate : NSObject <NSApplicationDelegate>{
    TheNotes *myNote;
}

@property (copy) TheNotes *myNote;
@property (assign) IBOutlet NSWindow *window;

@end

AppDelegate.m:

#import "AppDelegate.h"

@implementation AppDelegate
@synthesize myNote;


- (void)applicationDidFinishLaunching:(NSNotification *)aNotification{
    myNote = [[TheNotes alloc]init]; //Do I need to put it in -(id) init ?
}

- (void)applicationWillTerminate:(NSNotification *)notification{
    [myNote save];
}

@end

TheNotes.h:

#import <Foundation/Foundation.h>

@interface TheNotes : NSObject {
    NSString *theText;
    IBOutlet NSTextView *theTextView;// Do I need to alloc memory ?
}

-(void) save;
@property (copy) NSString *theText;

@end

TheNotes.m:

@implementation TheNotes
@synthesize theText;

- (void) save {
    NSLog(@"%@",theTextView.string);// Save is properly called, but this results (null).
    [NSKeyedArchiver archiveRootObject:theTextView.string toFile:@"..."];
}

@end

2 个答案:

答案 0 :(得分:1)

您需要自己回答的两个问题是:

  • 为什么我希望TextSaver能够了解文本视图?
  • 我在哪里可以告诉TextSaver文本视图?

第一个问题的另一个可能答案是“TextSaver创建了文本视图”,但我假设情况并非如此。

所以,你需要找到你认为你告诉TextSaver文本视图的位置,并确保是这种情况。

如果你没有做任何具体的事情来告诉TextSaver关于文本视图,而是期望它只是知道它,那么这可能是问题。

正如Phillip Mills在评论中提到的,仅仅声明一个名为theTextView的变量并不意味着TextSaver知道文本视图。编译器无法阅读英文:您选择的名称仅供您自己使用;编译器仅将它们视为标识符。它没有看到“theTextView”并且去了“哦,那个!就在那边;我会去拿它。“

为了让theTextView实际指向文本视图,您需要将文本视图放在那里。你通过作业来做到这一点。将theTextView公开为属性并将其从其他位置设置,或在TextSaver类中内部设置(在自己创建文本视图或从其他对象获取文本视图之后)。

我会将它设为一个属性(简称为textView),并从TextSaver和文本视图中拥有该属性。

答案 1 :(得分:0)

这是一个很好的例子,基本上就是你想要实现的目标,HTH。

有两个类,AppDelegate和TestViewController。 TestViewController有一个UITextView,每当用户在编辑UITextView时按下设备的主页按钮,就会调用AppDelegate的- (void)applicationDidEnterBackground:(UIApplication *)application方法并将注释打印到控制台(这里你可以保存注释)。

我使用applicationDidEnterBackground因为它是应用进入后台模式时调用的内容。

<强> AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    PVSTestViewController *nextScreen = [[PVSTestViewController alloc] init];
    self.delegate = nextScreen;      // Assign TestViewController as the AppDelegate's delegate.
    self.window.rootViewController = nextScreen;
    [self.window makeKeyAndVisible];
    return YES;
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    [self.delegate saveData]; // Called when the user presses the home button.
}

<强> AppDelegate.h

....

@protocol PVSAppDelegateProtocol <NSObject>

- (void)saveData;     // Any class that conforms to our protocol must implement this method.

@end

@interface PVSAppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;
@property (nonatomic, weak) id<PVSAppDelegateProtocol> delegate;   // Here we store the delegate class.

@end

<强> TestViewController.m

#import "PVSTestViewController.h"

@interface PVSTestViewController ()

@property (weak, nonatomic) IBOutlet UITextView *textView;

@end

@implementation PVSTestViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

- (void)saveData
{
    // This is called by the AppDelegate when the app goes into the background.
    NSLog([NSString stringWithFormat:@"Text is: %@", self.textView.text ]);
}

@end

<强> TestViewController.h

....

#import "PVSAppDelegate.h"

@interface PVSTestViewController : UIViewController <PVSAppDelegateProtocol>

@end