Search code examples
objective-cpropertiesparent

In Objective-C, how to make @property's accessible to other classes?


The original question remains below this update:

So further research indicates that my

"...missing setter or instance variable"

log messages are due to an unhinged .xib.

I originally thought that might be the case which is why I went through the process of re-connecting the outlets and properties in the graphic interface builder, but that seems to have been insufficient to repair the connections.

I restored the outlets as properties rather than iVars and reconnected again, still to no avail. So I'm in the process of remaking the .xib's from scratch. Stay tuned for the results.

Original question follows:

Having declared and synthesized properties in parent and sheet classes, and attempted therein to access the properties by their respective class.property names, Xcode rejects the code.

I posted a similar question recently and deleted it after being told there was not enough info to make a response, so I include here below a mini-app which shows how the relevant setup was in the real app of over 2000 lines of Objective-C, which built and ran properly before I attempted to add the Parent / Sheet properties feature.

I've indicated the compiler error messages with a prefix of ////. When I comment out the erroneous lines, the app with its .xib's builds and runs, dysfunctionally of course.

ParentClass.h

// ParentClass stuff belongs in the original main window controller
#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
@interface ParentClass : NSObject
{
    IBOutlet NSTextField * messageTextField;
    IBOutlet NSButton    * proceedButton;
}
@property (assign)  IBOutlet  NSWindow * window;
@property (strong)  NSMutableString * parentPropInfo;
- (IBAction) awakeFromNib;
- (IBAction) doCreate:(id)sender;
@end

ParentClass.m

#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
#import "ParentDelegate.h"
#import "ParentClass.h"
#import "SheetClass.h"
@implementation ParentClass
ParentDelegate     * MyDelegate;  // only confirms termination requests
NSWindowController * SheetController;
@synthesize parentPropInfo;
- (IBAction)awakeFromNib  {
    MyDelegate = [NSApplication sharedApplication].delegate;
    MyDelegate.ParentController = self;   // BTW, this property assignment works!
    SheetController = [[SheetClass alloc] initWithWindowNibName: @"SheetClass"];
    messageTextField.stringValue = @"Click Proceed button";
}
- (IBAction)doProceed*emphasized text*:(id)sender  {
    parentPropInfo = @"Hello!".mutableCopy;   // to be read by the sheet
    [NSApp runModalForWindow:SheetController.window];
    // Sheet is active now until it issues stopModal, then:

    messageTextField.stringValue = SheetController.sheetPropInfo;   // set by the sheet
////above gets ERROR "Property sheetPropInfo not found on object of type 'NSWindowController *'"

    messageTextField.stringValue = SheetController.window.sheetPropInfo;
////above gets ERROR "Property sheetPropInfo not found on object of type 'NSWindow *'"

    [NSApp endSheet: SheetController.window];
    [SheetController.window orderOut:self];
}
@end

SheetClass.h

#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
#import "ParentClass.h"
@interface SheetClass : NSWindowController
{
    IBOutlet NSTextField * propTextField;
    IBOutlet NSButton    * cancelButton;
}
@property (assign) IBOutlet NSWindow * window;
@property   NSMutableString * sheetPropInfo;
- (IBAction)awakeFromNib;
- (IBAction)doCancel:(id)sender;
@end

SheetClass.m

#import "SheetClass.h"
#import "ParentClass.h"
@implementation SheetClass
@synthesize sheetPropInfo;
- (IBAction)awakeFromNib  {

    propTextField.stringValue = self.window.sheetParent.parentPropInfo;  // set by the parent
////above gets ERROR "Property parentPropInfo not found on object of type 'NSWindow *'"

    sheetPropInfo = @"Goodbye!".mutableCopy;  // to be read by the parent
}
- (IBAction)doCancel:(id)sender  {
    [NSApp stopModal];
}
@end

I can find nothing in Apple documentation or extensive (three weeks now!) online search to offer any insight as to my abysmal ignorance. I apologize for the overwhelming batch of code needed to illustrate my problem! Where shall I obtain the information I need?


Solution

  • The error messages are perfectly clear. Just read them and think about them. Let's just take the first one. You are saying:

    messageTextField.stringValue = SheetController.sheetPropInfo;
    

    ...and getting this response from the compiler:

    // Property sheetPropInfo not found on object of type 'NSWindowController *'
    

    Well, think about the expression SheetController.sheetPropInfo and why the compiler cannot make sense of it. You have declared SheetController as follows:

    NSWindowController * SheetController;
    

    So that is all the compiler knows: SheetController is an NSWindowController. Well, sure enough, just as the compiler says, sheetPropInfo is not a property of NSWindowController. It is a property of SheetClass (which is not the same as NSWindowController; it is a subclass of NSWindowController).

    If you know that SheetController is in fact a SheetClass instance, you need to tell the compiler that fact. You must either declare SheetController as a SheetClass or cast it down from an NSWindowController to a SheetClass.