0

I am trying to implement an IBAction in one class (SuperDel) and access IBOutlet in another class (SubC).

The class method subMethod is suppose to change the value of NSString testin the viewer via KVC/KVO .

From the Object Library in Xcode I have added a controller object and linked it to custom class SubC. Then I bind test to SubC such that the Key Path is Value(SubC.test) in the bindings Inspector.

  • When I call subMethod from SubC via (IBAction)startC everything works fine.
  • When I call subMethod from SuperDel via (IBAction)start only NSLog displays.

It appears as the reciever self in subMethod is the root/cause of the problem, since the problem only appears when I call the method from another class (SuperDel).

Any suggestions on how to solve this problem?

UPDATE1: I have made several variants of the toy code below and the problem remains. I just can't get KVO and Cocoa-bindings to work unless I have IBAction and IBOutlet in the same m-file. @stevesliva's advice seem to indicate that self isn't the problem, since NSLog displays the correct class

UPDATE2: _test updates correctly and self points to the correct class. The only thing left is this line of code: [self didChangeValueForKey:@"test"], but this line shouldn't be necessary...

The view is correctly updated when the IBAction calls subMethod from within the SubC class; The view is never updated when IBAction is called from another class… and I have no idea why not.

Please help, this is driving me crazy.

SuperDel.h:

#import <Cocoa/Cocoa.h>

@interface SuperDel: NSObject <NSApplicationDelegate>
@property (assign) IBOutlet NSWindow *window;
- (IBAction)start:(id)sender;
@end

SuperDel.h:

#import "SuperDel.h"
#import "SubC.h"
@implementation SuperDel
- (IBAction)start:(id)sender {
    SubC *parc = [[SubC alloc]init];
    [parc subMethod];
}
@end

SubC.h:

#import <Foundation/Foundation.h>
@interface SubC : NSObject {
//    NSString *test;                           
}
@property NSString *test;
//- (IBAction)startC:(id)sender;
- (void)subMethod;
@end

SubC.m:

#import "SubC.h"
@implementation SubC
@synthesize test;                             
- (id)init
{
    self = [super init];
    if (self) {
        [self setValue:@"*" forKey:@"test"];
    }
    return self;
}
/*
- (IBAction)startC:(id)sender {
    [self subMethod];   
}
*/
- (void)subMethod{    
    [self willChangeValueForKey:@"test"];     // Shouldn't be necessary
    [self setValue:@"Foo" forKey:@"test"];    // This only changes View if the method is called from within the class, i.e. via (IBAction)startC
    NSLog(@"test = %@", _test);               // This always results in: test = Foo
    [self didChangeValueForKey:@"test"];      // Shouldn't be necessary
    NSLog(@"Self = %@", self);                // Self = <SubC: 0x10014ae30>
    NSLog(@"This always displays");           // This displays regardless if called from (IBAction)startC or (IBAction)start
}
@end
userjuicer
  • 123
  • 2
  • 9
  • I happen to have the book. For purposes of illustration, they're declaring the backing iVar for the property, which isn't really necessary and isn't standard, and that's what I was harping on. I thought maybe you were calling the `test` accessor rather that the `setTest` setter somehow. Regardless, the reason I'm not answering is that I don't know what's causing the issue you describe, and also assuming this code here is a synopsys of what you really have. It may be that you have multiple instances of SubC objects, and you're thinking you have fewer. You could NSLog the address of `self`. – stevesliva Nov 07 '14 at 04:32
  • It is the toy code of the real code. but the toy code displays the same problem as the real code. If I can't get the toy code to work I won't be able to get the real code to work. Tried NSLog as you suggested, see above – userjuicer Nov 07 '14 at 14:34
  • Are you still trying to solve this? If you are, can you clarify a few things: **firstly** when you talk about changing the value of ``test`` *in the viewer*, what do you mean by *viewer*? **secondly**, what kind of *controller object* did you add (i.e. what is its specific class), and **thirdly** what do you mean by '*linked it to custom class*'? Questions that mix bindings, kvo/kvc, and interface builder can be tricky to help with unless you're very precise about the set-up. – Paul Patterson Nov 11 '14 at 21:50

0 Answers0