数据封装,无法访问实例变量

时间:2012-11-06 20:33:23

标签: objective-c ios xcode

我在理解哪些类可以读取其他类中的变量时遇到一些麻烦。我在线阅读了许多不同的东西,似乎在这里找不到任何可靠的东西。在过去的两天里我试图让我的程序工作,但是没有类可以读取任何其他类变量。任何帮助都将非常感激。

这是我的ViewController.h:

@interface ViewController : UIViewController
{
    @public
    NSString *nameOfLabel;
}

@property (strong, nonatomic) IBOutlet UILabel *firstLabel;
- (IBAction)Switch:(id)sender;
- (IBAction)changeLabel:(UIButton *)sender;
-(NSString *) nameOfLabel;
@end

nameOfLabel是一个公共变量,应该可以被外部类访问,对吗?

ViewController.m:

#import "ViewController.h"
#import "NewView.h"

@interface ViewController ()
@end

@implementation ViewController

- (IBAction)Switch:(id)sender {
    NewView * new = [[NewView alloc] initWithNibName:nil bundle:nil];
    [self presentViewController: new animated:YES completion:NULL];
}
- (IBAction)changeLabel:(UIButton *)sender  {
    nameOfLabel = @"Test Name";
    _firstLabel.text = nameOfLabel;
}
-(NSString *) nameOfLabel   {
    return nameOfLabel;
}
@end

changeLabel按钮将* firstLabel.text更改为“测试名称”。

第二个类是NewView.h:

#import "ViewController.h"

    @interface NewView : UIViewController
    @property (strong, nonatomic) IBOutlet UILabel *secondLabel;
    - (IBAction)changeSecondLabel:(UIButton *)sender;
    @end

和NewView.m:

#import "NewView.h"

@interface NewView ()
@end

@implementation NewView
{
    ViewController *view;
}
- (IBAction)changeSecondLabel:(UIButton *)sender {
    view = [[ViewController alloc] init];
    _secondLabel.text = view.nameOfLabel;
}
@end

changeSecondLabel应该将secondLabel.text更改为nameOfLabel,即'Test name',但是,标签实际上消失了,这让我觉得无法访问nameOfLabel。我玩过nameOfLabel,使它成为@property然后合成它,并尝试将它放入{NSString * nameOfLabel;在@implementation下但我仍然得到相同的结果。

4 个答案:

答案 0 :(得分:0)

这一行:view = [[ViewController alloc] init];创建一个 new ViewController,它不知道你对其他一些ViewController做了什么。在你的情况下,它特别不知道在这个新的ViewController存在之前,changeLabel:被调用了。

答案 1 :(得分:0)

首先请阅读有关编码标准的信息,这不是一个好的做法:

  1. 名称变量如“new”

  2. 名称方法,如“Switch”

  3. 将UIViewController命名为“view”或“NewView”

  4. 关于逻辑: 这一切都搞砸了。你实际做的是用nameOfLabel创建viewController,它是空的,只在按下按钮时更改。我假设您按下该按钮以便更改。然后在切换操作上创建另一个viewController并显示它。然后从新的viewController内部创建另一个具有空nameOfLabel的新viewController,获取此空值并将其放在secondLabel中。

    有几种方法可以改变secondLabel:

    1. 当您想要更改secondLabel时,将nameOfLabel移动到模型并从那里读取,
    2. 因为你的新viewController是viewController的子节点,它保存了nameOfLabel,你可以通过调用[[self presentsViewController] nameOfLabel]来访问它,但首先使它成为属性,
    3. 通过指定的初始化程序传递nameOfLabel。

答案 2 :(得分:0)

当显示第二个视图控制器(NewView)时,它没有引用第一个视图控制器(ViewController)及其数据。

以下是一些建议。

  • 在现代Objective-C中,我建议使用属性而不是暴露变量。
  • 查看一般的命名。例如,“ViewController”不是一个好名字。
  • 如果属性是类的内部状态的一部分,则在类扩展中声明它。
  • 在呈现第二个视图控制器之前,请从第一个视图控制器设置对该字符串的引用。

ViewController.m的一部分:

@interface ViewController ()
@property (copy,nonatomic) NSString *nameOfLabel;
@end

@implementation ViewController

- (IBAction)Switch:(id)sender {
    NewView *new = [[NewView alloc] initWithNibName:nil bundle:nil];
    new.secondLabel.text = self.nameOfLabel;
    [self presentViewController: new animated:YES completion:NULL];
}

答案 3 :(得分:0)

好吧,如果你想要一个公共ivar访问的简单演示,语法是:

view->nameOfLabel;
    ^^

不是dot-syntax:

view.nameOfLabel;

(点语法只是通过访问器方法)。

多年来我只见过少数有保证的边缘案件;很少,很少有理由公开宣传伊娃(同样,受保护也很少是良好的选择)。