公共或私人变量声明和自我委托不确定?

时间:2013-12-11 16:22:27

标签: ios objective-c

我对Objective-C和iOS开发很新。本周,经过大量努力,我设法在模拟器中正确运行了一个小应用程序。

我通过阅读Matt Neuburg的“iOS 7编程基础知识”,在线教程的说明以及本网站的建议,获得了编程语言的基础知识。

我编写的代码(显然),但我不完全理解为什么我需要在代码中进行一些调整才能使其正常工作。

该应用程序是一个基本的解决方案,为您的信息解决“风三角”。它需要做的就是将一些用户定义的变量放在正确的公式中,并显示结果。

我复制了.h和.m文件。简单地说:.h声明了7个变量;文本字段中的5个用户输入; 2个标签显示2个计算结果;一个启动计算动作的按钮。

使用以下代码,我不明白:

  • 为什么我被迫说明我的变量前面有一个下划线要在实现中使用

  • 为什么在加载视图后我被迫为变量声明.delegate为'self'

有什么建议让这个'应用'更合乎逻辑,更容易理解(我自己)?

//
//  ViewController.h
//  WindTriangle
//

#import <UIKit/UIKit.h>

#define M_PI        3.14159265358979323846264338327950288   /* pi */

float windDegreesFloat;
float windSpeedFloat;
float courseDesiredFloat;
float trueAirSpeedFloat;
float magneticVariationFloat;

float headingCalculatedFloat;
float groundSpeedCalculatedFloat;

@interface ViewController : UIViewController<UITextFieldDelegate>

@property (weak, nonatomic) IBOutlet UITextView *instructionsText;

@property (weak, nonatomic) IBOutlet UITextField *windDegrees;
@property (weak, nonatomic) IBOutlet UITextField *windSpeed;
@property (weak, nonatomic) IBOutlet UITextField *courseDesired;
@property (weak, nonatomic) IBOutlet UITextField *trueAirSpeed;
@property (weak, nonatomic) IBOutlet UITextField *magneticVariation;

@property (weak, nonatomic) IBOutlet UILabel *headingCalculated;
@property (weak, nonatomic) IBOutlet UILabel *groundSpeedCalculated;


- (IBAction)calculatePressed:(id)sender;

@end

//
//  ViewController.m
//  WindTriangle
//

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    self.windDegrees.delegate = self;
    self.windSpeed.delegate = self;
    self.courseDesired.delegate = self;
    self.trueAirSpeed.delegate = self;
    self.magneticVariation.delegate = self;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)calculatePressed:(id)sender {

    windDegreesFloat = [_windDegrees.text floatValue];
    windSpeedFloat = [_windSpeed.text floatValue];
    courseDesiredFloat = [_courseDesired.text floatValue];
    trueAirSpeedFloat = [_trueAirSpeed.text floatValue];
    magneticVariationFloat = [_magneticVariation.text floatValue];


    headingCalculatedFloat = ( courseDesiredFloat - magneticVariationFloat ) + ( 180 / M_PI ) * asin(( windSpeedFloat / trueAirSpeedFloat) * sin(( M_PI * ( windDegreesFloat - ( courseDesiredFloat - magneticVariationFloat))) / 180));

    NSString * headingCalculatedString = [NSString stringWithFormat:@"%.1f", headingCalculatedFloat];

    _headingCalculated.text = headingCalculatedString;


    groundSpeedCalculatedFloat = sqrt(pow( trueAirSpeedFloat , 2) + pow(windSpeedFloat , 2) - (2 * trueAirSpeedFloat *windSpeedFloat * cos((M_PI * ( courseDesiredFloat - windDegreesFloat + ((180 / M_PI) * asin(( windSpeedFloat / trueAirSpeedFloat ) * sin((M_PI * ( windDegreesFloat - courseDesiredFloat )) / 180))))) / 180)));

    NSString * groundSpeedCalculatedString = [NSString stringWithFormat:@"%.1f", groundSpeedCalculatedFloat];

    _groundSpeedCalculated.text = groundSpeedCalculatedString;

}

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    return [textField resignFirstResponder];
}

@end

我也是StackOverflow的新品牌。非常感谢您的意见。

4 个答案:

答案 0 :(得分:2)

嘿,所以对于你的第一个问题,下划线表示实例变量。有时回来,你不能在目标c中这样做。如果您声明了属性,则必须在合成后通过self.property调用它。所以下划线只是调用一个实例。

至于在这种情况下设置委托时的第二个问题,你实际上是将UITextField的IBOutlet的委托设置为你输入代码的viewcontroller。委托负责控制器之间的交互和观点。这允许视图控制器管理UITextFieldDelegate的某些方法

答案 1 :(得分:2)

当您声明@property时,例如:

@property (weak, nonatomic) UITextField *property;

编译器创建公共变量,您可以通过self.property和私有变量访问它,您可以使用下划线_property访问它。 在您的实现中,您通过添加下划线来读取私有变量。

委托是一种让对象通知另一个对象的方法。在您的示例中:

self.windDegrees.delegate = self;

self.windDegrees是一个文本字段,此指令意味着此文本字段(windDegrees)将通知当前类(ViewController)发生了某些事情,例如方法:

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    return [textField resignFirstResponder];
}
每次文本字段返回时都会调用

答案 2 :(得分:1)

这里有几件事情错了。你的.h文件应该是:

//
//  ViewController.h
//  WindTriangle
//

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

@property (weak, nonatomic) IBOutlet UITextView *instructionsText;

@property (weak, nonatomic) IBOutlet UITextField *windDegrees;
@property (weak, nonatomic) IBOutlet UITextField *windSpeed;
@property (weak, nonatomic) IBOutlet UITextField *courseDesired;
@property (weak, nonatomic) IBOutlet UITextField *trueAirSpeed;
@property (weak, nonatomic) IBOutlet UITextField *magneticVariation;

@property (weak, nonatomic) IBOutlet UILabel *headingCalculated;
@property (weak, nonatomic) IBOutlet UILabel *groundSpeedCalculated;

- (IBAction)calculatePressed:(id)sender;

@end

您不希望声明所有这些不必要的全局变量。您无需重新定义标准M_PI宏。而且您无需告诉全世界您的班级符合UITextField协议。

在你的.m文件中,你应该替换它:

@interface ViewController ()

@end

使用:

@interface ViewController () <UITextViewDelegate, UITextFieldDelegate>

@end

此外,无论您为某个属性引用其中一个生成的实例变量,都应该更改引用以使用该属性。例如:

变化:

windDegreesFloat = [_windDegrees.text floatValue];

为:

windDegreesFloat = [self.windDegrees.text floatValue];

在使用下划线变量而不是属性的任何地方都这样做。

例如,使用self.windDegrees.delegate = self;是告诉文本字段您的视图控制器(self)将处理文本字段中的事件。

答案 3 :(得分:0)

感谢所有反馈。我将您的反馈代码更改为以下代码。 因为它以前工作,它仍然可以,但正确(呃)编码。 我开始明白为什么我必须删除.h中的全局变量,在哪里放置正确的协议声明,以及_真正代表的地方。欢迎提出其他意见或建议。全部!

//
//  ViewController.h
//  WindTriangle
//

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController<UITextFieldDelegate>

@property (weak, nonatomic) IBOutlet UITextView *instructionsText;

@property (weak, nonatomic) IBOutlet UITextField *windDegrees;
@property (weak, nonatomic) IBOutlet UITextField *windSpeed;
@property (weak, nonatomic) IBOutlet UITextField *courseDesired;
@property (weak, nonatomic) IBOutlet UITextField *trueAirSpeed;
@property (weak, nonatomic) IBOutlet UITextField *magneticVariation;

@property (weak, nonatomic) IBOutlet UILabel *headingCalculated;
@property (weak, nonatomic) IBOutlet UILabel *groundSpeedCalculated;

- (IBAction)calculatePressed:(id)sender;

@end

//
//  ViewController.m
//  WindTriangle
//

#import "ViewController.h"

@interface ViewController () <UITextViewDelegate, UITextFieldDelegate>

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    self.windDegrees.delegate = self;
    self.windSpeed.delegate = self;
    self.courseDesired.delegate = self;
    self.trueAirSpeed.delegate = self;
    self.magneticVariation.delegate = self;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)calculatePressed:(id)sender {

    float windDegreesFloat = [self.windDegrees.text floatValue];
    float windSpeedFloat = [self.windSpeed.text floatValue];
    float courseDesiredFloat = [self.courseDesired.text floatValue];
    float trueAirSpeedFloat = [self.trueAirSpeed.text floatValue];
    float magneticVariationFloat = [self.magneticVariation.text floatValue];


    float headingCalculatedFloat = ( courseDesiredFloat - magneticVariationFloat ) + ( 180 / M_PI ) * asin(( windSpeedFloat / trueAirSpeedFloat) * sin(( M_PI * ( windDegreesFloat - ( courseDesiredFloat - magneticVariationFloat))) / 180));

    NSString * headingCalculatedString = [NSString stringWithFormat:@"%.1f", headingCalculatedFloat];

    _headingCalculated.text = headingCalculatedString;


    float groundSpeedCalculatedFloat = sqrt(pow( trueAirSpeedFloat , 2) + pow(windSpeedFloat , 2) - (2 * trueAirSpeedFloat *windSpeedFloat * cos((M_PI * ( courseDesiredFloat - windDegreesFloat + ((180 / M_PI) * asin(( windSpeedFloat / trueAirSpeedFloat ) * sin((M_PI * ( windDegreesFloat - courseDesiredFloat )) / 180))))) / 180)));

    NSString * groundSpeedCalculatedString = [NSString stringWithFormat:@"%.1f", groundSpeedCalculatedFloat];

    _groundSpeedCalculated.text = groundSpeedCalculatedString;

}

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    return [textField resignFirstResponder];
}

@end