有人能简单解释一下Objective C代表的工作方式吗?

如何解决有人能简单解释一下Objective C代表的工作方式吗?

| 好的,这似乎是一个重复的问题,但是如果您支持我并阅读了整个问题,您就会明白我为什么要提出这个问题。 我在网络上和这里都看到了许多不错的示例和说明,但是我无法理解。对我来说,理解为什么和如何操作很重要,因此与其使用文档中的一些示例(顺便说一句,我确实很了解Apple Docs,Im与php.net文档一起使用,还有大量示例),因为那时我只是不明白。 我想要两个课,一个gardenClass。它具有一个包含花的数组,每个花都从flowerClass实例化。因此,flowerClass不知道实例化哪种花园。有时候它只是尖叫着喝水。 因此,如果有人可以为我解释这一点,我将不胜感激! 我尝试了一下,这是我根据你们从我那里得到的信息来试一试: 我的花园
#import \"Flower.h\"

@interface MyGarden : NSObject <WateringDelegate>
{
    Flower *pinkFlower;
}
@end
我的花园
#import \"MyGarden.h\"
#import \"Flower.h\"

@implementation MyGarden

- (void) giveWaterToFlower
{
    NSLog(@\"Watering Flower\");
}

- (void)viewDidLoad
{
    pinkFlower = [[Flower alloc] init];
    [pinkFlower setDelegate:self];
    [pinkFlower startToGrow];
}
@end
花h
@protocol WateringDelegate <NSObject>
@required
- (void) giveWaterToFlower;
@end

@interface Flower : NSObject
{
    id <WateringDelegate> delegate;
}

@property (retain) id delegate;
- (void) startToGrow;
@end
花.m
#import \"Flower.h\"

@implementation Flower

@synthesize delegate;

- (void) needWater
{
    [[self delegate] giveWaterToFlower];
}

- (void) startToGrow
{
    [NSTimer scheduledTimerWithTimeInterval:10.0 target:self selector:@selector(needWater) userInfo:nil repeats:YES];
}
@end
我尚未导入任何UIKit或基金会,因为我现在尝试在这里进行与委托相关的工作... 那么,这是正确的吗?     

解决方法

委托是您为应用程序实现自定义行为的地方,该行为会影响另一个类(例如Cocoa框架中的普通对象)的工作方式。 在其他不使用委托模式的语言中,您可以将对象子类化以更改其行为。使用Objective-C也可以做到这一点,但是委托的好处在于,您不必每次都要进行细微更改时都可以继承子类,一个对象可以是多个其他对象的委托。 因此,请考虑一个控制器类,该类拥有一个带有一些控件的窗口,也许是一个信息表,一个工具栏等。您可以将控制器设置为这些控件的委托,以便在控件需要有关其功能的更多信息时他们应该去找您的控制器。您可能想要自定义窗口的大小调整方式,用户在表视图中选择一行时发生的情况,信息的显示方式等等。这些都是控件使用其委托协议中定义的方法对其委托(您的控制器)进行的调用。如果幸运的话,您可以编写所有自定义代码,而无需子类化并将其拆分为多个文件。 另一个好处是您只需要实现您关心的委托方法。如果默认行为很好,则无需执行任何操作。 因此,在您的示例中,flower类将具有某种使用“ waterMe \”方法的委托协议。委托(也许是花园类,或其他所有类)可以根据您的选择来实现此目的,并且只有在花类需要时才调用该委托。值得注意的是,委派在框架中最有用,在框架中,您有一个对象以通用方式工作,可能会被覆盖以完成不同的事情。在您自己的代码中,通常可以直接将自定义行为添加到您自己的对象中,除非您确实打算以通用方式使用它。换句话说,不要试图花时间去创建一个可以正常表现的类,而实际上,您只会使它以一种特定的方式表现。     ,如Marc所示,委托模式在某些情况下很有用。问题在于,苹果公司使用它们的时间远远超过了应使用的时间。特别是,Apple尝试(失败的是imo失败了)使用委托来实现基本的事件机制。 这违背了委托模式的目的,该模式将类的行为模块化为组件。事件不代表行为:它们代表(通常是独立的)根据事件发生而发生的动作(即,动作取决于事件,但是效果可能很大程度上独立于引发事件的对象)。 最大的问题是,一个事件只能有一个委托处理程序,而在其他语言中有很多有效的情况,我们可能希望有一个事件的多个独立使用者。例如,在C#中,“ 4”运算符用于将事件处理程序添加到对象的事件中,从而允许事件的观察者数量不受限制。不幸的是,Objective-C没有任何内置的事件机制,Apple的核心框架类也没有采用这种事件模式。 至少可以说使用委托进行事件。此外,由于只有一个消费者,因此消费者与生产者紧密相关。因此,另一个消费者不可能更改生产者的委托(这是可行的,但不是明智的选择)。 Apple如何使用代表进行实际事件的示例是“ 5”方法。那是一件大事。为什么只允许一件事取决于所选择的行? “解决方案”(尽管它更多的是一种解决方法)是让父级使用其子级的伪事件委托方法公开其自身的委托。但这仅意味着更多的工作和更多的出错机会。 Apple如何正确使用委托模型(就模式而言,这尤其如此)的一个示例是“ 6”方法。此方法允许用户卸载和定义tableView的行为,并且提供多个实现是没有意义的。 关于委托模式的一件好事是,它同时支持组合和继承。也就是说,您可以派生一个实现自己的委托方法的控制器类,然后可以实例化该类,或者可以简单地使用通用控件来构成您的类,并自己为该控件提供委托方法。 但是,我也不喜欢将当前(父)对象作为组件(子)对象的代表进行传递,因为这会导致类污染和概念不匹配(整个类现在只为它的组成部分之一,而不是属于类本身的概念)。更好的方法是提供一个特殊的映射对象,该对象实现必要的委托方法。但是,由于这在Objective-C中并不方便,因此不幸的是,前者最常被惯例采用。     ,就目前而言,当花要喝水时,它叫
self.delegate giveWaterToFlower
。 default8ѭ默认设置为
MyGarden
,因此当花要喝水时,
MyGarden
中的
giveWaterToFlower
方法会被调用。如果实现了
wateringCan
对象,则
wateringCan
可以做
[pinkFlower setDelegate:self];
。然后,当花要喝水时,
self.delegate giveWaterToFlower
会在
wateringCan
中调用
giveWaterToFlower
方法,这可能会提供比默认值更多或更少的水。同样,您可以实现一个
gardenHose
对象,该对象还提供了一个
giveWaterToFlower
方法。园艺软管只能与花园保持一定距离,因此只能覆盖特定花朵中的代表。 但是设计模式是
flower
已将其
giveWaterToFlower
方法委托给另一个对象。
flower
对象不知道是谁提供了
giveWaterToFlower
方法。您可以在
flower
中包括默认的
giveWaterToFlower
方法,并用
self.delegate = self;
初始化
flower
对象     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res