Tyler Pfaff
Tyler Pfaff

Reputation: 5032

Why is my property nil when setting it using self.propertyname instead of _propertyname

In the viewDidLoad() below, setting my property with self.textToAnalyze results in the property being nil in the debugger, while setting the property directly using _textToAnalyze shows that the property is no longer nil. Why is this?

//
//  TextStatsViewController.m
//  colorSwitcher

#import "TextStatsViewController.h"

@interface TextStatsViewController ()
@property (weak, nonatomic) IBOutlet UILabel *colorfulCharactersLabel;
@property (weak, nonatomic) IBOutlet UILabel *outlinedCharactersLabel;

@end

@implementation TextStatsViewController

-(void)setTextToAnalyze:(NSAttributedString *)textToAnalyze
{

}
-(void)viewDidLoad
{
    _textToAnalyze=[[NSAttributedString alloc] initWithString:@"test" attributes:@{NSForegroundColorAttributeName : [UIColor greenColor],NSStrokeWidthAttributeName :@-3}]; //setting it here with the underscore shows that this property is not nil in the debugger
  //self.textToAnalyze=[[NSAttributedString alloc] initWithString:@"test" attributes:@{NSForegroundColorAttributeName : [UIColor greenColor],NSStrokeWidthAttributeName :@-3}];  //setting it here with the accessor shows that this property is nil in the debugger
}

-(void)updateUI
{
    self.colorfulCharactersLabel.text =[NSString stringWithFormat:@"%d colorful characters",[[self charactersWithAttribute:NSForegroundColorAttributeName] length]];

    self.outlinedCharactersLabel.text =[NSString stringWithFormat:@"%d outlined characters",[[self charactersWithAttribute:NSStrokeWidthAttributeName] length]];
}
-(NSAttributedString *)charactersWithAttribute:(NSString *)attributeName
{
    int index=0;
    NSMutableAttributedString* characters=[[NSMutableAttributedString alloc] init];
    while(index < [self.textToAnalyze length])
    {
        NSRange range;
        id value = [self.textToAnalyze attribute:attributeName atIndex:index effectiveRange:&range];
        if(value)
        {
            [characters appendAttributedString:[self.textToAnalyze attributedSubstringFromRange:range]];
            index=range.location+range.length;
        }else{
            index++;
        }
    }
    return characters;
}

-(void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [self updateUI];
}
@end


//
//  TextStatsViewController.h
//  colorSwitcher


#import <UIKit/UIKit.h>

@interface TextStatsViewController : UIViewController
@property (nonatomic,strong)NSAttributedString* textToAnalyze;
@end

Upvotes: 1

Views: 299

Answers (1)

LombaX
LombaX

Reputation: 17364

Because you have an empty setter.

-(void)setTextToAnalyze:(NSAttributedString *)textToAnalyze
{

}

when you do self.textToAnalyze = something is the same of doing [self setTextToAnalyze:something], so the instance variable is never set.

Change your custom implementation like this:

-(void)setTextToAnalyze:(NSAttributedString *)textToAnalyze
{
    _textToAnalyze = textToAnalyze;
}

or simply remove it, assuming that you have declared textToAnalyze as a @property in the .h file:

@property (nonatomic) NSAttributedString *textToAnalyze;

(moreover, the property must be strong if you want the passed value to be retained)

Upvotes: 7

Related Questions