【问题标题】:getting value of global variable from .m to another .m将全局变量的值从 .m 获取到另一个 .m
【发布时间】:2012-12-27 08:24:53
【问题描述】:

我尝试通过 2 种方式将全局变量的值从 .m 获取到另一个 .m:

首先,我尝试将 viewController.m 类导入另一个 .m 类并尝试检索值,但收到链接器错误。

其次,我只是用字符串名称创建了 extern,然后它就开始完美地工作了。

我的问题是为什么 import 给了我错误以及 extern 变量如何识别来自该特定类的字符串名称?
(即:如果我在不同的类中有 2 或 3 个具有相同名称的变量,我输入 extern 和字符串名称,我会得到哪个值,因为我没有导入任何类。)

还有,附加问题:你什么时候真正导入这个类?

【问题讨论】:

  • 买一本关于“c”语言的书并学习它。您需要了解“c”才能使用objective-c。 Objective-c 只是“c”的扩展,一个严格的超集。这些问题只是相当简单的“c”问题。
  • 基本上,如果我创建一个方法/道具,我需要将其导入另一个类以获取方法中的值。如果我使用 extern 命令,它将在整个应用程序中显示该变量的最新值。至少这就是我测试代码并检查的内容。我曾在 java 中工作并使用点运算符连接其他类变量,在这里看起来有点不同。直到现在我正在处理 viewcontoller 类本身而不使用任何其他类现在我想在其他类之间传输值。

标签: ios class ios5 import ios6


【解决方案1】:

我知道这已经得到了详细的回答,但我只是想澄清一下。

在 .m 文件中声明您希望私有的数据。对于您希望其他对象可以访问的数据,请在标题 .h 文件中声明。为所有声明使用属性:

  //myViewController.h
  @interface myViewController: UIViewController

  @property (assign) int myInt;
  @property (strong) NSString* someString;

  @end

您可以通过向 myViewController 传递消息来从另一个对象访问这些属性:

  [myViewController setMyInt:20];    //setter
  [myViewController someString];    //getter

或者你可以使用等效的点表示法

  myViewController.myInt = 20;
  myViewController.someString;

(您需要在任何想要访问这些的对象中#include "myViewController.h"

在 myViewController 中,您可以使用 'self' 访问它们:

  self.myInt;
  self.someString;

这是通过 setter/getter 的中介访问。支持变量可以直接从 myViewController 内部(但不能从任何其他对象)以_myInt_someString 访问。在 init 和 dealloc 方法之外不建议这样做。

属性封装了实例变量的声明默认getter和setter的创建,所以不需要单独声明变量,只需要自己制作访问器即可更改默认行为。

这里也请参考我的回答:
Should I declare variables in interface or using property in objective-c arc?

【讨论】:

  • 谢谢他。根据问题,我得到了两个答案 1 是使用一个方法并从另一个 .m 类执行它以获得返回类型。 2. 有外部变量。 根据您的回答,我创建了:@property (strong) NSString* someString;并包含 .h 文件,但错误指出在对象类型 ViewController 上找不到该属性?
【解决方案2】:

首先,我尝试将 viewController.m 类导入另一个 .m 类并尝试检索该值,但我收到了链接器错误。

您从不导入 .m(实现)文件。您只能导入 .h(标头)文件。

我的问题是为什么 import 给了我错误

在 C 中,有一条规则是任何(非static)具有特定名称的全局函数或变量必须定义一次。对于一个变量,写它的类型和名称​​定义它。对于一个函数,实现定义了它。因此,在两个不同的代码文件中具有相同名称的全局函数或变量将失败。他们会发生冲突。

导入文件意味着获取文件的整个源并将其插入其中。当您将 A.m“导入”到 B.m 中时,A.m 的整个源代码都将插入到 B.m 中。这意味着 A.m 中的每个声明现在都显示在程序的两个代码文件中——A.m 和 B.m,因此会出现错误。

您可以多次声明(但不能定义)一个全局变量或函数。您可以使用extern 声明一个变量而不定义它。使用extern 声明它允许您使用一个变量,即使它实际上并未在同一个代码文件中声明。

以及如何使用外部变量 识别来自该特定类的字符串名称? (即:如果 我在不同的类中有 2 或 3 个具有相同名称的变量,我 输入 extern 和字符串名称,我会得到哪个值,因为我不是 导入任何类。)

如上所述,您的程序中只能有 一个 具有给定名称的非static 全局变量。在不同的文件中具有相同名称的变量将是错误的。非static 全局变量和函数可以通过程序的名称从程序的任何其他部分访问(并且它通过链接的魔力工作)。


通常,将在许多文件中使用的全局变量的最佳实践是在 .m 文件中定义它(就像你正在做的那样),并在对应的 .h 文件中声明它extern到那个 .m 文件。然后导入该标头的其他文件将自动访问该变量。

【讨论】:

  • 感谢 newacct。这真是很棒的解释。它有帮助。所以我在做什么是对的?此外,我已经在 viewDIdLoad() 中声明了变量,现在我在 viewDidAppear 中执行它并且它的工作完美。我还创建了一个方法并从另一个 .m 类执行该方法,该方法又根据本文前面的讨论返回一个字符串。即使这样也很好?
【解决方案3】:

当您需要访问一个类的属性和方法时,您确实会导入一个类。这听起来可能太明显了,但事实就是如此。类是 OOP 的封装概念的化身。

可以通过多种方式将变量从一个点获取到另一个点,一种可以使用 userdefaults 工具,您可以在应用程序委托中拥有该变量,然后在不同的类中访问该值,或者您可以在您的目标视图控制器并让源视图控制器在转换到目标之前设置该属性..仅举几例。根据场景,还有很多正确和错误的方法。

将视图控制器 A 导入到另一个视图控制器 B 中,仅仅为了访问 A 中的值似乎有点过头了(如果不是完全不恰当地使用导入机制的话)。

这个问题进一步解释了externs,我没有接触过他们,

Objective-C static, extern, public variables

希望这会有所帮助。

【讨论】:

  • 基本上,如果我创建一个方法/道具,我需要将其导入另一个类以获取方法中的值。如果我使用 extern 命令,它将在整个应用程序中显示该变量的最新值。至少这就是我测试代码并检查的内容。我曾在 java 中工作并使用点运算符连接其他类变量,在这里看起来有点不同。直到现在我正在处理 viewcontoller 类本身而不使用任何其他类现在我想在其他类之间传输值。
  • 感谢我现在正在创建示例的链接。
  • 您可以使用的一种方法是使用键值观察来观察属性的值,因此当原始更改时您将获得委托方法调用。假设 A 是您的第一个带有字符串的 vc,而 B 是您要将其发送到的那个。您可以执行类似 [A addObserver:b forKeyPath:@"interestingString"...] 的操作,然后在 B 中实现 - (void)observeValueForKeyPath.. 对于实际签名,请在 developer.apple.com 上查找 KVO。这有帮助吗?
  • 谢谢尼基尔。帮我解决这个问题。我在视图控制器中创建了一个名为 -(void)check 的方法;其中方法中的值是 NSString *test=@"check";我在 2 视图控制器中导入了 viewcontoller,现在如何从该方法中获取变量??
  • 由于我看不到您的整个代码,因此我不确定上下文,但这是执行您所要求的一种方法。在 vc1.h +(NSString *)getMyString;在 vc1.m +(NSString *)getMyString { return @"check"; } in vc2.h #import "vc1.h" in vc2.m - (void)someFunction { NSLog(@"这里是字符串:%@",[vc1 getMyString]); }
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多