Objective c Xcode os x:为什么drawRect无法访问实例数据

Objective c Xcode os x:为什么drawRect无法访问实例数据,objective-c,macos,storyboard,nsview,drawrect,Objective C,Macos,Storyboard,Nsview,Drawrect,我试图在自定义视图中绘制一些东西,但不确定为什么drawRect无法访问其实例数据。以下是我尝试的步骤 创建Mac OS X应用程序,并选中“使用情节提要” 在情节提要中,删除视图,然后在同一位置的视图下添加新的自定义视图。(如果视图未被删除,我尝试过,相同) 将EEGView类指定给新添加的自定义视图 然后跑。从日志信息中,您会注意到,尽管实例变量已初始化和更新,但drawRect无法访问实例数据 在viewCtroller.m中 - (void)viewDidLoad { [supe

我试图在自定义视图中绘制一些东西,但不确定为什么drawRect无法访问其实例数据。以下是我尝试的步骤

  • 创建Mac OS X应用程序,并选中“使用情节提要”
  • 在情节提要中,删除视图,然后在同一位置的视图下添加新的自定义视图。(如果视图未被删除,我尝试过,相同)
  • 将EEGView类指定给新添加的自定义视图
  • 然后跑。从日志信息中,您会注意到,尽管实例变量已初始化和更新,但drawRect无法访问实例数据

    在viewCtroller.m中

    - (void)viewDidLoad {
        [super viewDidLoad];
    
        // Do any additional setup after loading the view.
        myView = [[EEGView alloc] init];
        //[self.view addSubview:myView];
        //Start Timer in 3 seconds to show the result.
        NSTimer* _timerAppStart = [NSTimer scheduledTimerWithTimeInterval:2
                                                          target:self
                                                        selector:@selector(UpdateEEGData)
                                                        userInfo:nil
                                                         repeats:YES];
        [[NSRunLoop currentRunLoop] addTimer:_timerAppStart forMode:NSDefaultRunLoopMode];
        }
        - (void)UpdateEEGData
    {
        //    NSLog(@"UpdateEEGData.....1");
        //    myView.aaa = 200;
        //    myView.nnn = [NSNumber numberWithInteger:myView.aaa];
    
        // make sure this runs on the main thread
        if (![NSThread isMainThread]) {
            // NSLog(@"NOT in Main thread!");
            [self performSelectorOnMainThread:@selector(updateDisplay) withObject:nil waitUntilDone:TRUE];
        }else
        {
            [self.view setNeedsDisplay:YES];
    
        }
    
        NSLog(@"UpdateEEGData.....2");
        [myView setAaa:400];
        myView.nnn = [NSNumber numberWithInteger:myView.aaa];
    
    
        // make sure this runs on the main thread
        if (![NSThread isMainThread]) {
            // NSLog(@"NOT in Main thread!");
            [self performSelectorOnMainThread:@selector(updateDisplay) withObject:nil waitUntilDone:TRUE];
        }else
        {
            [self.view setNeedsDisplay:YES];
    
        }
    }
        -(void)updateDisplay
    {
        [self.view setNeedsDisplay:YES];
    }
    
    在我的自定义视图类EEGView.m中

    @implementation EEGView
    @synthesize aaa;
    @synthesize nnn;
    
    -(id)init{
    
        self = [super init];
        if (self) {
            aaa = 10;
            nnn = [NSNumber numberWithInteger:aaa];
    
            NSLog(@"init aaa: %i", aaa);
            NSLog(@"init nnn: %i", [nnn intValue]);
        }
    
        return self;
    }
    
        - (void)drawRect:(NSRect)dirtyRect {
        [super drawRect:dirtyRect];
    
        // Drawing code here.
    
        NSLog(@"drawRect is here");
        NSLog(@"drawRect aaa: %i", aaa);
        NSLog(@"drawRect nnn: %i", [nnn intValue]);
    }
    
    @end
    
    我错过什么了吗?在Xcode 7.2和7.2中测试。但是如果我不选中“使用故事板”,它就会工作

    还是一个Xcode错误

    谢谢你的建议。
    提前谢谢

    如果您在故事板上添加了
    EEGView
    视图,则不应在
    viewDidLoad
    中实例化一个视图。您已经分配/初始化了一个新的脚本,但它与脚本为您创建的脚本没有任何关系。因此,由情节提要创建的一个实例调用了
    drawRect
    ,但是您在
    viewDidLoad
    中创建的单独实例中设置了属性,该实例从未添加到视图层次结构中(因此,它的
    drawRect
    也不会被调用)


    当故事板实例化视图控制器的视图时,它将为您实例化
    EEGView
    。您所需要做的就是为该视图连接一个
    IBOutlet
    ,以便从视图控制器获取对它的引用。(例如,您可以控制从情节提要场景中的
    EEGView
    拖动到您在助手编辑器中调出的视图控制器的
    @界面

    如果您在情节提要上添加了
    EEGView
    视图,则不应该在
    viewDidLoad
    中也实例化一个视图。您已经分配/初始化了一个新的脚本,但它与脚本为您创建的脚本没有任何关系。因此,由情节提要创建的一个实例调用了
    drawRect
    ,但是您在
    viewDidLoad
    中创建的单独实例中设置了属性,该实例从未添加到视图层次结构中(因此,它的
    drawRect
    也不会被调用)


    当故事板实例化视图控制器的视图时,它将为您实例化
    EEGView
    。您所需要做的就是为该视图连接一个
    IBOutlet
    ,以便从视图控制器获取对它的引用。(例如,您可以控制从情节提要场景中的
    EEGView
    拖动到您在助手编辑器中调出的视图控制器的
    @界面

    与手头的问题无关,但是如果您使用
    scheduledTimerWithTimeInterval
    创建计时器,您也不必将其添加到运行循环中。已经安排好了。如果您使用
    timerWithTimeInterval
    创建计时器,则您可以将其添加到运行循环中,但如果您已经计划了它,则不会。与当前问题无关,但如果您使用
    scheduledTimerWithTimeInterval
    创建计时器,则不必将其添加到运行循环中。已经安排好了。如果使用
    timerWithTimeInterval
    创建计时器,则可以将其添加到运行循环中,但如果已经对其进行了调度,则不会添加。