我在Lynda.com上为objective-c做了一个tuturial,并且运行了这个示例代码。这是ViewController.m文件的一部分。练习背后的想法是创建一个包含自定义元素的选择器对象。 以下代码工作得很好,并给了我一个选择"快乐"并且"悲伤"作为选项:
@implementation ViewController
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return 1;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
return [[self moods] count];
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
return self.moods[row];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.moods = @[@"happy",@"sad"];
}
但是,我更喜欢方括号来点缀语法,正如您所看到的,我在几个不同的地方进行了实验。 return [[self moods] count
在教程中被写为return [self.moods count]
,但是我想使用方括号来验证它是否仍然有用,我知道发生了什么,所以我更改了它并且它运行得很好。但是,我一直试图用self.moods = @[@"happy",@"sad"];
做同样的事情,因为我不喜欢它的样子。我试过了:
[[self moods] initWithObjects: @"happy",@"sad", nil];
但我只是一个空白的选择器和一个警告"表达结果未使用"。我尝试在表达式之前添加_moods =
,但仍然有一个空白的选择器。这有什么不对?
答案 0 :(得分:2)
我假设您在@property (strong, nonatomic) NSArray *moods;
工作之后在界面中声明了self.moods
。
自动创建Setter和getter方法setMoods
和getMoods
。
以下是点语法归结为
的方法// These are equivalent
self.moods = @[@"happy",@"sad"];
[self setMoods:@[@"happy",@"sad"]]; // Literal declaration
[self setMoods:[[NSArray alloc] initWithObjects:@"happy",@"sad",nil]]; // Full declaration
这是有效的,因为您使用“文字”方式声明NSArray *,其中包括“分配”和“初始化”。
- (instancetype)initWithObjects:
是一个实例方法,应该在已经使用alloc
分配的实例变量上调用。您试图初始化一个从未在内存中分配过的变量。
稍微更清洁的选择是:
[self setMoods:[NSArray arrayWithObjects:@"happy",@"sad",nil]];
arrayWithObjects:
包括分配和初始化。
答案 1 :(得分:2)
[[self moods] initWithObjects: @"happy",@"sad", nil];
未按预期行事的原因是由于对点语法以及与使用方括号发送消息的关系有何误解。
Dot语法是“语法糖”,也是推荐访问类属性的方法,例如问题中的mood
属性。 Dot语法只是Objective-C中访问器(setter / getters)的简写。一个简单的例子可能有助于澄清这一点。
当点语法发现自己位于赋值运算符的右侧或作为消息的接收者时,将调用getter方法。
// These two are equivalent
NSArray *allMoods = self.moods
NSArray *allMoods = [self moods]
// These two are equivalent
NSUInteger count = [self.moods count];
NSUInteger count = [[self moods] count];
当点语法发现自己位于赋值运算符的左侧时,将调用setter方法。
// These two are equivalent
self.moods = @[@"happy", @"sad"];
[self setMoods:@[@"happy", @"sad"];
使用点语法不仅是一个很好的简写,它使你的意图更清晰,你的代码的新手立刻意识到moods
是你班级的财产。
另外,[[self moods] initWithObjects: @"happy",@"sad", nil];
无效的原因是因为-initWithObjects:
是NSArray
的初始化程序,应该在+alloc
之后立即调用 。在上面的代码段中,[self moods]
返回已存在的NSArray
或懒惰地实例化一个-initWithObjects
。为完整起见,NSArray *myArray = [[NSArray alloc] initWithObjects:@"happy", @"sad", nil];
应按如下方式使用:
{{1}}
答案 2 :(得分:1)
[self moods]
引用它的方式只能在表达式的右侧使用,它会调用属性的getter。 self.moods = ...
实际上是[self setMoods:...]
所以请尝试[self setMoods:@[@"happy",@"sad"]]
答案 3 :(得分:1)
您想要阅读@property声明以及它如何合成" getter和setter方法。你想要做的是"设置"情绪属性:
[self setMoods: @[@"happy",@"sad"]];