gpt4 book ai didi

objective-c - 在 Cocoa Objective C 中的类之间发送数据

转载 作者:太空狗 更新时间:2023-10-30 03:50:56 24 4
gpt4 key购买 nike

我大约一个月前开始为 iPhone 编程,发现该网站非常有用。所以我想有人可以帮助我。

我想我了解@property 和@synthesese 如何工作以及使用 setter 和 getter 的基础知识,但我有一个问题。

假设我有 3 个类:函数、Class1 和 Class2。

Functions 是一个包含所有数据的类,Class1 和 Class2 从中读取数据并向其写入新数据(修改数据)。然而,Class1 和 Class2 都会创建自己的 Functions 实例,因为它基本上只是数据的蓝图。

因此,如果 Class1 向 Functions 写入或“设置”一些数据(比方说)5,而 Class2“获取”它,Class2 将返回 0,因为 Class1 仅将 5 写入其 Functions 实例,而 Class2 看不到。

我想首先,对吗?第二,我该怎么做才能让 Class1 和 Class2 可以看到要获取和设置的相同数据。

感谢您的帮助。我意识到这可能包括一个我还没有学过的主题,但如果是的话,我很想知道它是什么,这样我就可以学习它。

最佳答案

您有许多选项都可以追溯到确保 Class1 和 Class2 使用“共享对象”的相同实例。

  1. 明确地从外部将同一个实例传递给Class1和Class2,而不是让Class1和Class2自己创建一个实例;或
  2. 为 Functions 类提供一个单独的初始值设定项,然后确保 Class1 和 Class2 使用它;或
  3. 使用称为注册表模式的设计模式,并确保 Class1 和 Class2 从注册表中获取函数类的实例;或
  4. 使用依赖注入(inject)(复杂)。

场景 (1) 是最容易理解的,因为它完全是这样的:

Functions *funcs = [[Functions alloc] init];

Class1 *obj1 = [[Class1 alloc] initWithFunctions:funcs];
Class2 *obj2 = [[Class2 alloc] initWithFunctions:funcs];
/* or alternatively use setters after initialization */

场景 (2) 是下一个最简单的并且非常常见。 Cocoa 为它的许多类提供单例初始化器。每当您看到 +shared... 作为初始化程序的前缀时,它可能会返回一个单例。

@implementation Functions

+(id)sharedFunctions {
static Functions *sharedFunctions = nil;

@synchronized(self) {
if (sharedFunctions == nil) {
sharedFunctions = [[self alloc] init];
}

return sharedFunctions;
}
}

@end

静态变量只初始化一次,这意味着您可以通过检查它的初始值(只发生一次)将对象的实例延迟加载到其中。对该方法的每次后续调用都会返回相同的实例。

Functions *f1 = [Functions sharedFunctions];
Functions *f2 = [Functions sharedFunctions];

/* f1 == f2; */ // always

与其他语言相比,选项 (3) 在 Objective-C 中并不多见,它实现了与单例大致相同的目标。这个想法是你有一个可以按键查找的对象字典。任何需要访问注册表项的东西都只是向注册表请求它自己的实例。通常注册表本身是一个单例。

选项 (4),即依赖项注入(inject),实际上是一个非常优雅的解决方案,它以增加复杂性为代价提供了许多好处。好处来自这样一个事实,即您已确保依赖项始终松散耦合(这使得交换实现和独立地对依赖项进行单元测试变得更加简单)。复杂性来自用于检索所需实例的非标准机制。

依赖注入(inject)围绕着没有对象实例化它自己的依赖的想法。而不是依赖其他东西来提供这些依赖关系。那个“别的东西”被称为依赖注入(inject)容器。依赖项注入(inject)容器实际上是注册表模式之上的一层,因为该容器要么保存依赖项的预构建实例,要么知道如何实例化新实例。

在最简单的情况下,依赖注入(inject)正是我在选项 (1) 中演示的。您甚至不需要依赖项注入(inject)容器即可实现此目的。

为了提高复杂度,依赖注入(inject)引入了 DI 容器的概念,它封装了许多现有的设计模式(注册表,如选项 (3) 所示,单例(可能,但不严格)和工厂(知道如何创建它管理的对象的新实例)。

演示 DI 容器的完整实现可能超出了这个问题的范围,但从公共(public)接口(interface)的角度来看,一个实现可能如下所示:

DIContainer *container = [DIContainer sharedContainer];

[container registerClass:[ClassA class]];
[container registerClass:[ClassB class]];
[container registerDependentProperty:@selector(setClassA:)
withInstanceOf:[ClassA class]
forClass:[ClassB class]];

ClassB *obj = [container makeInstanceOfClass:[ClassB class]];
NSLog(@"ClassB's -classA type = %@", [[obj classA] class]);

我只是在这篇文章的中间打出了这个词,所以不要假设它是 100% 准确的,但你明白了这个概念。容器已被指示,当它初始化 ClassB 的实例时,它必须调用 -setClassA:,使用 ClassA 的实例,它也根据定义的规则进行初始化在容器中(在这种情况下,没有 ClassA 的依赖项,因此它只返回一个普通实例。

如果您对这个答案一无所知,请记住选项 (1) 和 (2) ;)

关于objective-c - 在 Cocoa Objective C 中的类之间发送数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4210469/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com