Home > Mobile >  Why these NSView subclass instances do not get initialised [Objective-C]?
Why these NSView subclass instances do not get initialised [Objective-C]?

Time:06-26

I am trying to understand how NSLayoutAnchor works in Objective-C by converting a simple Swift app to it. The Swift app creates an NSView subclass which sets its layer's background color to a randomly generated color (with an extension to NSColor), then creates two instances of it in AppDelegate (inside application:didFinishLaunchingWithOptions), then creates the array of constraints, add the two views to the superview, activates the constraints and... that's it.
In my Objective-C version, where I have tried to convert everything, it seems that the two custom NSView subclass instances never get initialised. A step-by-step debugging shows their value to be = nil, and while the app launches, the console says:

-[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[0]

From that I deduced something may be wrong with the way I initialised my NSView subclass, but not even with duck-explaining I can find what may be wrong. This is the code in ColorView.m ("RandomColor.h") is the extension to get the randomColor method:

#import "ColorView.h"
#import "RandomColor.h"

@implementation ColorView

- (id)initWithFrame:(NSRect)frameRect {
    self = [super initWithFrame:frameRect];
    
    if (self) {        
        self.wantsLayer = YES;
        self.layer = [[CALayer alloc] init];
        
        self.layer.backgroundColor = [[[NSColor alloc] randomColor] CGColor];
    }
    
    NSLog(@"Color View Initialized");
    return self;
}

@end

Here is the extension, if you want to test it, but that doesn't seem to be the problem:

@implementation NSColor (RandomColor)
- (NSColor *)randomColor {
    CGFloat r = drand48();
    CGFloat g = drand48();
    CGFloat b = drand48();
    CGFloat alpha = 1.0;
    
    return [NSColor colorWithRed:r green:g blue:b alpha:alpha];
}

@end

In AppDelegate.h I declared two ColorView properties called leftView and rightView, while in AppDelegate.m:

@synthesize leftView;
@synthesize rightView;

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    leftView.translatesAutoresizingMaskIntoConstraints = NO;
    rightView.translatesAutoresizingMaskIntoConstraints = NO;
    
    NSView *view = [self.window contentView];
    [self.window setBackgroundColor:[NSColor systemMintColor]];
    
    if (view) {
        [view addSubview:leftView];
        [view addSubview:rightView];
        
        [NSLayoutConstraint activateConstraints:@[
            [leftView.topAnchor constraintEqualToAnchor:[view topAnchor]],
            [leftView.leftAnchor constraintEqualToAnchor:[view leftAnchor]],
            [leftView.rightAnchor constraintEqualToAnchor:[view centerXAnchor]],
            [leftView.widthAnchor constraintGreaterThanOrEqualToConstant:150],
            [leftView.heightAnchor constraintEqualToConstant:100],
            [rightView.centerXAnchor constraintEqualToAnchor:[view centerXAnchor] constant:50],
            [rightView.centerYAnchor constraintEqualToAnchor:[view centerYAnchor]],
            [rightView.widthAnchor constraintEqualToConstant:100],
            [rightView.heightAnchor constraintEqualToConstant:100]
        ]];
    }
}

I also looked at the archived documentation for NSView subclassing, stored here, but most of it was either not compiling or not helping in a meaningful way.
Could you please tell me where I am wrong in this code, or what am I missing? Please also correct me if the title is not appropriate for the question.
Thank you so much

CodePudding user response:

In the sample code leftView and rightView are never allocated.

Adding leftView=[[ColorView alloc]initWithFrame:someRect]; (and similar for rightView) should make the code work.

  • Related