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

问题描述:

我想在自定义视图中绘制某些东西,但不知道为什么drawRect无法访问其实例数据。这是我尝试的步骤。Xcode os x:为什么drawRect无法访问实例数据

  1. 创建一个Mac OS X应用程序,并使用故事板检查。
  2. 在故事板中,删除视图,然后在视图下的同一位置添加新的自定义视图。 (我试过,如果视图没有删除,相同)。
  3. 将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错误?

任何意见赞赏。 在此先感谢。

+0

无关手头上的问题,但如果你创建具有'scheduledTimerWithTimeInterval'的计时器,您不必将其添加到运行循环中。它已经安排好了。如果你使用'timerWithTimeInterval'创建了定时器,那么你将它添加到运行循环中,但是如果你已经安排了它,则不会。 – Rob

+0

谢谢。得到它了。 – iSleep

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

当故事板实例化视图控制器的视图时,它会为您实例化您的EEGView。所有你需要做的就是为这个视图挂上一个IBOutlet,以便从你的视图控制器获得对它的引用。 (例如,您可以控制从EEGView拖动至情节板中的场景到@interface为您在助理编辑拉升视图控制器)。

+0

是的,你是对的。谢谢! – iSleep