Obj-C:未调用委托方法

发布于 2024-12-25 17:05:10 字数 2639 浏览 2 评论 0原文

我是 iOS 开发新手,正在学习 2010 年秋季的斯坦福 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

I'm new to iOS Dev, I'm following the Stanford CS193P classes for Fall 2010. I'm on assignment 3 and I'm setting my delegate to my view and by using the debugger I'm noticing the call to my delegate method won't happen, I don't understand what could be happening. My code is as follows:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

苏辞 2025-01-01 17:05:10
  1. 在设置图形视图委托的行上放置一个断点。
  2. 检查 graphView 变量。是零吗?

这种情况一直发生在我身上,而且总是(几乎总是),因为我无法将插座连接到界面生成器中的视图。

  1. Put a break point on the line where you set the graph view's delegate.
  2. Inspect the graphView variable. Is it nil?

This happens to me all the time and it's always (well nearly always) because I have failed to connect the outlet to the view in interface builder.

孤独难免 2025-01-01 17:05:10

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

最有可能的问题是您的类实例(即其他类的委托)在调用委托方法之前被释放。通过使此类成为其他类的属性或实例变量或使用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-call/

Let's say class YourClass is a delegate for some other class. And delegate methods are not called, despite that delegate property is set up.

Most probably the problem is that your class instance, that is a delegate for your other class is released before the delegate method is called on it. Make it more persistent by making this class a property or instance variable of other class or by using dispatch_once. For example,

Change

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

by

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

This problem occurs because in ARC everything that is created inside a method (and is not an instance variable) is released, when method finishes. And delegate methods cannot be called, that are invoked by some background process.

I've written a big blog post on this problem. This is pretty common situation.
http://alwawee.com/wordpress/2013/07/31/on-xmppframework-delegate-method-not-being-called/

老街孤人 2025-01-01 17:05:10

我对此有一些建议:

  1. 如果您将变量作为属性,则不需要 iVar(内部变量),它仍然可以工作,我从来不知道它不可以。

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. 您需要在视图中设置委托才能使用它。

GraphViewController

@implementation GraphViewController

( ... )

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


( ... )

@end

Ive got a few pointers for ya on this one:

  1. You don't need an iVar (internal Variable) if you have the variable as a property, it will still work, I've never know it not to.

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. You need to set your delegate in your view to be able to use it.

GraphViewController

@implementation GraphViewController

( ... )

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


( ... )

@end
沫雨熙 2025-01-01 17:05:10

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

[self.delegate functionForGraph:nil];

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

当然,这只是为了测试委托实现,您实际上应该在 GraphView.m 中的其他方法中使用此委托调用,该方法能够处理您的请求者

You are not calling the delegate functions anywhere in your GraphView.m. Try testing it out by placing this piece of code in your - (id)initWithFrame:(CGRect)frame method, right before you return.

[self.delegate functionForGraph:nil];

and see if it logs any message to the console.

Of course this is just to test the delegate implementation, you should actually be using this delegate call in some other method in your GraphView.m which is able to process your requestor

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文