You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delegate未触发方法:SquareView代理调用返回nil问题排查

Delegate代理未触发问题排查与修复

问题描述

我查了其他Delegate相关问题,但没找到合适的解决方案。所有配置看起来正常,滑块数值变化能在日志里看到,但SquareView调用numberOfSquaresInSquareView()方法时从未触发,而且SquareView的代理调用返回nil。changeSquareCount()方法能正常工作,日志显示数值已成功保存,我觉得已经接近解决但漏了些细节。

相关代码

squareView.h

#import <Cocoa/Cocoa.h>

NS_ASSUME_NONNULL_BEGIN
@class SquareView;
@protocol SquareViewDelegate <NSObject>

- (NSNumber *)numberOfSquaresInSquareView:(SquareView *)squareView;

@end

@interface SquareView : NSView
@property (nonatomic, weak) id<SquareViewDelegate> delegate;

@end

NS_ASSUME_NONNULL_END

squareView.m

#import "SquareView.h"

@implementation SquareView
@synthesize delegate;

- (id)initWithFrame:(NSRect)frame
{
    self = [super initWithFrame:frame];
    if (self)
    {
    }
    return self;
}

- (void)drawRect:(NSRect)dirtyRect {
    [super drawRect:dirtyRect];
    NSLog(@"drawing rect");
    [[NSColor redColor]set];

    //NSNumber *num = ; //cound pass in nil, dont matter
    NSLog(@"squares to draw: %@", [delegate numberOfSquaresInSquareView:self]);
    // Drawing code here.
}

@end

AppController.h

#import <Foundation/Foundation.h>
#import "SquareView.h"
//@class SquareView;
NS_ASSUME_NONNULL_BEGIN

@interface AppController : NSObject <SquareViewDelegate>

@property (retain) IBOutlet SquareView *squareView;

- (IBAction)changeSquareCount:(id)sender;
@end

NS_ASSUME_NONNULL_END

AppController.m

#import "AppController.h"

@implementation AppController
{
    NSNumber *_squareCount;
}
@synthesize squareView = _squareView;
- (void)awakeFromNib
{
    [_squareView setDelegate:nil];
    _squareCount = @(10);
    [_squareView setNeedsDisplay:YES];
}

- (void)changeSquareCount:(id)sender
{
    _squareCount = @([sender intValue]);
    NSLog(@"square count stored: %@",_squareCount);
    [_squareView setNeedsDisplay:YES];
}
-(NSNumber *)numberOfSquaresInSquareView:(SquareView *) squareView
{
    NSLog(@"triggering numberOfSquaresInSquareView");
    return _squareCount;
}

@end

修复方案

1. 修正代理赋值错误

问题核心在AppController的awakeFromNib方法中——你将_squareView的代理设置为nil,导致SquareView无法找到代理对象调用方法。只需将代理设为self即可:

- (void)awakeFromNib
{
    [_squareView setDelegate:self]; // 替换原有的nil为self
    _squareCount = @(10);
    [_squareView setNeedsDisplay:YES];
}

2. 增加代理安全判断(可选但推荐)

在SquareView的drawRect方法中,调用代理前先判断代理是否存在且响应目标方法,避免因代理为空导致崩溃:

- (void)drawRect:(NSRect)dirtyRect {
    [super drawRect:dirtyRect];
    NSLog(@"drawing rect");
    [[NSColor redColor]set];

    NSNumber *squareNum = nil;
    // 先判断代理是否响应方法
    if ([self.delegate respondsToSelector:@selector(numberOfSquaresInSquareView:)]) {
        squareNum = [self.delegate numberOfSquaresInSquareView:self];
    }
    NSLog(@"squares to draw: %@", squareNum);
    // Drawing code here.
}

3. 规范属性访问(可选)

在SquareView中建议使用self.delegate而非直接访问实例变量delegate,符合Objective-C属性访问的最佳实践。

内容的提问来源于stack exchange,提问作者Hyperian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 15:13:18