objective-c - id 类型实例变量向实例方法发送消息

标签 objective-c delegates protocols

我关于 stackoverflow 的第一个问题,所以请保持温和。我尝试寻找答案,但我真的需要这方面的帮助。

问题在于从 Neal Goldstein 的 Objective-C for Dummies 中学习委托(delegate)

他在Transaction.h

中有如下内容
#import <Cocoa/Cocoa.h>
@class Budget;

@interface Transaction : NSObject {

  Budget   *budget;  
  double    amount;
  NSString *name;
  id        delegate;
}

//some init method

@end

@protocol TransactionDelegate

@required

- (void) spend: (Transaction *) aTransaction;

//additional optional method

@end

--

//然后在 Transaction.m 他有这个

#import "Transaction.h"
#import "Budget.h"

@implementation Transaction

@synthesize budget, delegate , amount; 

- (void) spend {

  if ([delegate respondsToSelector:@selector(spend:)])
    [delegate spend:self]; 
}

- (id) initWithAmount: (double) theAmount forBudget: (Budget*) aBudget {
  if (self = [super init]) {
    budget = aBudget;
    [budget retain];
    amount = theAmount;
  }
  return self;
}

- (void) dealloc {

  [budget release];
  [super dealloc];
}

@end

我无法理解 Transaction.m 文件中的花费方法

id 类型实例变量可以调用包含它的类中的任何方法吗? 我知道 respondsToSelector 是一个 NSObject 方法,它告诉编译器是否已经实现了一个方法。但是,id 类型的委托(delegate)如何调用该方法呢?编译器甚至不知道它是什么对象...

请帮忙!

附言如果有人对优秀的 Objective-C 书籍有任何推荐,我将不胜感激。我想进入 iPhone 开发,但我认为我需要先很好地掌握 Objective-C 的基础知识。

谢谢!

最佳答案

是的,您可以向delegate 变量发送任何消息,因为它的类型是id

你写了这个:

[delegate spend:self];

编译器将其转换为对 objc_msgSend 函数的调用,如下所示:

objc_msgSend(delegate, @selector(spend:), self);

在运行时objc_msgSend 函数在delegate 的类(及其父类(super class))的方法表中搜索与选择器 spend:.

顺便说一句,我们通常这样声明delegate变量:

id<TransactionDelegate> delegate;

这会通知编译器delegate 将是一个符合TransactionDelegate 协议(protocol)的对象。当您尝试向 delegate 发送消息时,此声明将帮助 Xcode 为您提供更好的自动完成功能。如果您以这种方式声明您的 delegate setter 方法或属性,编译器还会在编译时检查您是否将其设置为符合协议(protocol)的对象。

关于objective-c - id 类型实例变量向实例方法发送消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15345411/

相关文章:

iPhone:检测两指触摸

ios - 我可以在包中嵌入自定义字体并从 ios 框架访问它吗?

iphone - 用于 iPad 的 UITableViewCell 中的 UIButtons

c# - 我可以在 C# 泛型约束中指定 'supertype' 关系吗?

ios - 从自定义 UITableViewCell 委托(delegate) TabBar

unit-testing - 客户端-服务器应用程序上的 TDD

swift - 如何在Struct中实现协议(protocol)可选方法?

iphone - 调用类别方法时发送到实例的无法识别的选择器

ios - 如何在 iOS Swift 中将 UIButton 操作从 View Controller 调用到另一个 View Controller ?

ios - 如何在 Swift 中强制覆盖孙子类?