使用self.propertyname而不是_propertyname设置时,为什么我的属性为nil

Tyl*_*aff 1 properties objective-c ios

viewDidLoad()下面,设置我的财产self.textToAnalyze在结果property之中nil在调试器,而直接设置属性使用_textToAnalyze表明,该属性不再为零.为什么是这样?

//
//  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
Run Code Online (Sandbox Code Playgroud)

Lom*_*baX 7

因为你有一个空的二传手.

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

}
Run Code Online (Sandbox Code Playgroud)

当你这样self.textToAnalyze = something做时[self setTextToAnalyze:something],所以实例变量永远不会被设置.

像这样更改自定义实现:

-(void)setTextToAnalyze:(NSAttributedString *)textToAnalyze
{
    _textToAnalyze = textToAnalyze;
}
Run Code Online (Sandbox Code Playgroud)

或者只是删除它,假设您已textToAnalyze在.h文件中声明为@property:

@property (nonatomic) NSAttributedString *textToAnalyze;
Run Code Online (Sandbox Code Playgroud)

(此外,如果您希望保留传递的值,则属性必须很强)

  • @AlaksiejN.在集合的这一点上,你通常会更好地利用这样的逻辑.也就是说,最好使传递进行各种状态更改,然后根据当前包含的状态告诉所有内容更新其可视状态.如果你有每个对象触发基于每个属性更改重新计算渲染状态,你很快就会遇到由大量不必要的计算引起的巨大性能瓶颈. (3认同)
  • @AlaksiejN.简单的例子; Person对象有`firstName`和`lastName`.它们有时(但并非总是)一个接一个地改变.如果你有一个重新计算东西的`firstName`的观察者,那么`lastName`的观察者会重新计算一组重叠的东西,那么你最终会做不必要的工作.*但是*如果只有一个被更改,你仍然需要触发重新计算,这会驱动到原始类/属性之外的"完成更改,更新可视状态"逻辑. (3认同)