【问题标题】:"Instance variable 'xxx' accessed in class method....why?“在类方法中访问的实例变量‘xxx’......为什么?
【发布时间】:2012-10-24 19:13:48
【问题描述】:

所以请原谅我,因为我对 stackoverflow 和一般的 ios 编程非常陌生。

我正在尝试更改我拥有的按钮的文本,将当前文本替换为日期字符串 (dateStringForInput) 我从另一个类传入。该按钮名为myTodayButton,并在我的.h 文件中为我的班级inputMilesViewController 声明... @property (strong, nonatomic) IBOutlet UIButton *myTodayButton;

以下是我的 .m 中的代码。

+(void) changeButtonText:(NSString*) dateStringForInput{

     NSLog(@"we got to changebuttontext");
     [_myTodayButton setTitle:dateStringForInput forState:UIControlStateNormal];
}

我收到以下错误“在类方法中访问的实例变量“_myTodayButton”。

我知道这是用类方法而不是实例方法编写的,但我不知道如何使这种更改发生。提示调用changeButtonText 的按钮位于另一个正在创建dateStringForInput 的类中。

【问题讨论】:

    标签: iphone xcode methods instance instance-variables


    【解决方案1】:

    试试这样...

    对于 (+) 实例。

    + (void) changeButtonText: 只能访问 self 对象。

    --第 1 步: 从 header 文件中删除以下行

    @property (strong, nonatomic) IBOutlet UIButton *myTodayButton;
    

    --第二步:

    • 在你的类文件中全局添加UIButton *myTodayButton..
    • 表示在@implementation之前声明

    例如:在 .m 文件中

    #import "Controller.h"
    UIButton *myTodayButton // Add like this before @implementation
    
    @implementation Controller
    

    对于 (-) 实例

    - (void) changeButtonText: 只能访问实例方法

    【讨论】:

      【解决方案2】:

      将方法更改为实例方法而不是类方法(“-”而不是“+”)创建类的实例,然后像这样简单地调用它:

      MyClass *classInstance = [[MyClass alloc] init];
      [classInstance changeButtonText:@"stringText"];
      

      还建议为 IBOutlets 设置弱属性。

      @property (nonatomic, weak) IBOutlet UIButton *myButton;
      

      [编辑]

      关于 segues 的第二个问题。首先,您真的需要一个不同的视图控制器来简单地显示 UIDatePicker 吗?我通常使用 actionSheet 将它们显示在同一个 UIViewController 中,它需要做一些工作才能做得恰到好处,但可以解决这个问题。如果你愿意,我可以发布代码吗?

      无论如何,如果您想保留当前设置,我会执行以下操作:

      1. 在包含按钮的 ViewController 中,在 .h 文件中创建一个新的公共 NSString 属性。

        @property (nonatomic, strong) NSString *dateString;

      2. 在包含日期选择器的视图控制器中,在用户选择日期后,覆盖 perpareForSegue 方法。在这里获取目标视图控制器(即上面第一点中创建的具有按钮和新字符串属性的视图控制器)并设置 dateString。

        - (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
        
        MyViewController *todayViewController = (MyViewController*)[segue destinationViewController];
        [todayViewController setDateString:@"valueYouRequire"];
        

        }

      3. 在带有按钮的 ViewController 中,将 viewDidLoad 中的按钮标题设置为 dateString。

        • (void)viewDidLoad { [超级 viewDidLoad];

        if (self.dateString) [self.myTodayButton setTitle:self.dateString forState:UIControlStateNormal]; }

      [编辑]

      如果您想沿着 actionSheet 路线走,然后使用按钮将此方法添加到 ViewController 并调整帧大小以满足您的需求。下面的方法创建一个日期选择器,将其添加到 actionSheet 并显示 actionSheet。

      - (IBAction) datePressed:(id)sender {
      
      if (!_actionSheet) {
      
      _actionSheetFrame = CGRectMake(0, self.view.frame.size.height - 373, 320, 403);
      _actionSheetBtnFrameOk = CGRectMake(20, 330, 280, 50);
      _actionSheetBtnFreameCancel = CGRectMake(20, 275, 280, 50);
      _pickerFrame = CGRectMake(0, 50, 320, 216);
      
      
          _actionSheet = [[UIActionSheet alloc] initWithTitle:@"Select Date" delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil otherButtonTitles:@"OK", nil];
          _datePicker = [[UIDatePicker alloc] init];
          [_datePicker setDatePickerMode:UIDatePickerModeDate];
      
          [_actionSheet addSubview:_datePicker];
      }
      
      [_datePicker setMaximumDate:[NSDate date]];
      
      [_actionSheet showInView:self.view.superview];
      [[[_actionSheet subviews] objectAtIndex:kActionBtnIndexOk] setFrame:_actionSheetBtnFrameOk];
      [[[_actionSheet subviews] objectAtIndex:kActionBtnIndexCancel] setFrame:_actionSheetBtnFreameCancel];
      
      [_actionSheet setFrame:_actionSheetFrame];
      [_datePicker setFrame:_pickerFrame];
      

      }

      您还必须实现 UIActionSheetDelegate 方法,以便在用户选择所需日期后设置按钮的文本。

      #pragma mark - UIActionSheet Delegate Methods
      
      - (void) actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex {
      
          if (buttonIndex == 0) {
              [self.myTodayButton setTitle:self.dateStringFromSelectedDate forState:UIControlStateNormal];
          }
      }
      

      【讨论】:

      • 非常感谢本尼!这摆脱了我的错误,但是按钮的标题没有改变。如果我想更改按钮 myTodayButton 的显示文本,我的代码是否正确? [_myTodayButton setTitle:dateStringForInput forState:UIControlStateNormal]; }
      • 你的代码看起来不错迈克尔,有两个可能的问题。您尚未将实际按钮链接到在代码中表示它的变量,即 myTodayButton。打开 Storyboard 或 XIB 文件并控制从停靠栏中的 UIViewController 图标拖动到按钮并松开,然后您应该能够将按钮链接到名为 myTodayButton 的属性。如果你已经这样做了,那么你传入的字符串可能是 nil 吗?中断该方法并检查 dateStringForInput 是什么值,它可能是 nil?!
      • 再次感谢,我想我刚刚意识到我的问题是什么......完全不同的主题,所以我应该创建一个新帖子,但也许你可以阐明一些。我有场景 1,它有“今天”按钮,当你点击那个按钮时,它会转到场景 2,其中包含日期选择器和另一个将日期转换为字符串的按钮,将其发送到场景 1,并且应该更改文本按钮,但是当我点击场景 2 上的按钮时,它会返回到场景 1,这似乎被重置为应用程序首次加载时...有没有办法在不重新加载的情况下切换到场景 2 并返回场景 1?跨度>
      • 基本上我想暂停场景 1,跳转到场景 2,然后返回场景 1 并使用新的日期值。
      • 我为此编辑了我的答案。它的格式有点乱,但我想你会明白的。祝你好运!
      【解决方案3】:

      类方法无法访问实例变量,这就是您收到您所看到的错误的原因。

      需要将方法改为实例方法:

      - (void)changeButtonText:(NSString *)dateStringForInput;
      

      然后您需要将包含该方法的类的实例的引用传递或获取到调用该方法的类。

      我希望这是有道理的...如果您需要任何说明,请添加评论!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-09-24
        • 2014-08-21
        • 1970-01-01
        • 1970-01-01
        • 2021-06-03
        • 2017-06-18
        • 2017-03-20
        • 1970-01-01
        相关资源
        最近更新 更多