Obj-C:没有调用委托方法

时间:2012-01-10 15:17:00

标签: objective-c ios delegates protocols

我是iOS Dev的新手,我正在关注2010年秋季的Stanford CS193P课程。我正在完成作业3并且我将我的代表设置为我的视图并使用调试器我注意到了调用我的委托方法不会发生,我不明白会发生什么。我的代码如下:

GraphViewController.h:

@interface GraphViewController : UIViewController <GraphViewDelegate> {
    GraphView *graphView;
    float scale;
}

@property (retain) IBOutlet GraphView *graphView;
@property float scale;

- (IBAction)zoomIn;
- (IBAction)zoomOut;

@end

GraphViewController.m:

@implementation GraphViewController

@synthesize graphView, scale;

- (NSString *)functionForGraph:(GraphView *)requestor {
    NSLog(@"%@", @"culo peluo");
    return @"lol";
}

- (float)scaleForGraph:(GraphView *)requestor {
    return self.scale;
}

- (IBAction)zoomIn {

}

- (IBAction)zoomOut {

}

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {

    }
    return self;
}

- (void)dealloc
{
    [super dealloc];
}

- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.graphView.delegate = self;
    self.scale = 20;
    [self.graphView setNeedsDisplay];
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

@end

GraphView.h:

@class GraphView;

@protocol GraphViewDelegate 
- (NSString *)functionForGraph:(GraphView *)requestor;
- (float)scaleForGraph:(GraphView *)requestor;
@end

@interface GraphView : UIView {
    id <GraphViewDelegate> delegate;
}

@property (assign) id <GraphViewDelegate> delegate;

@end

GraphView.m:

@implementation GraphView

@synthesize delegate;

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    return self;
}

- (void)drawRect:(CGRect)rect
{
    CGFloat cgScale = [self.delegate scaleForGraph:self];
    [AxesDrawer drawAxesInRect:self.bounds originAtPoint:self.center scale:cgScale]; 
}


- (void)dealloc
{
    [super dealloc];
}

@end

4 个答案:

答案 0 :(得分:8)

  1. 在设置图表视图委托的行上放置一个断点。
  2. 检查graphView变量。这是不是?
  3. 这种情况一直发生在我身上,而且总是(几乎总是如此),因为我无法将插座连接到界面构建器中的视图。

答案 1 :(得分:3)

让我们说类YourClass是其他类的委托。尽管设置了delegate属性,但不会调用委托方法。

最有可能的问题是,在调用委托方法之前,会释放您的类实例,即其他类的委托。通过将此类作为其他类的属性或实例变量或使用dispatch_once使其更具持久性。例如,

更改

YourClass *instance = [[YourClass alloc] init];

通过

@property(nonatomic, strong) YourClass *instance;
self.instance = [[YourClass alloc] init]; 

出现此问题是因为在ARC中,方法完成时会释放在方法内创建的所有内容(并且不是实例变量)。并且无法调用委托方法,这些方法由某些后台进程调用。

我写了一篇关于这个问题的大博文。这是非常常见的情况。 http://alwawee.com/wordpress/2013/07/31/on-xmppframework-delegate-method-not-being-called/

答案 2 :(得分:1)

我在这个问题上有一些指示:

  1. 如果您将变量作为属性,那么您不需要iVar(内部变量),它仍然有效,我永远不会知道它。
  2. <强> GraphView

    @interface GraphView : UIView {
    
    }
    
    @property (assign) id <GraphViewDelegate> delegate;
    
    @end
    

    GraphViewController

    @interface GraphViewController : UIViewController <GraphViewDelegate> {
    
    }
    
    @property (retain) IBOutlet GraphView *graphView;
    @property float scale;
    
    - (IBAction)zoomIn;
    - (IBAction)zoomOut;
    
    @end
    
    1. 您需要在视图中设置代理才能使用它。
    2. <强> GraphViewController

      @implementation GraphViewController
      
      ( ... )
      
      - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
      {
          self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
          if (self) {
              self.delegate = self;
          }
          return self;
      }
      
      
      ( ... )
      
      @end
      

答案 3 :(得分:0)

您没有在GraphView.m的任何位置调用委托功能。尝试在返回之前将这段代码放在- (id)initWithFrame:(CGRect)frame方法中进行测试。

[self.delegate functionForGraph:nil];

并查看它是否将任何消息记录到控制台。

当然,这只是为了测试委托实现,您应该在GraphView.m中使用能够处理requestor

的其他方法使用此委托调用