Ios 静态变量在多个目标之间的行为如何?
我对Objective-C.m文件中全局范围中定义的Ios 静态变量在多个目标之间的行为如何?,ios,objective-c,iphone,xcode,xctest,Ios,Objective C,Iphone,Xcode,Xctest,我对Objective-C.m文件中全局范围中定义的静态变量的行为有问题。具体地说,我看到同一个变量在同一代码中引用的对象的不同实例取决于从XCTest目标执行时的作用域 在.m文件中定义的全局静态变量在主目标和XCTest目标之间的行为如何?下面是我看到的问题的一个例子: 设置代码 Manager.m #import "Manager.h" // This is the variable of interest! static Manager *sharedManager = nil; @
静态
变量的行为有问题。具体地说,我看到同一个变量在同一代码中引用的对象的不同实例取决于从XCTest目标执行时的作用域
在.m文件中定义的全局静态变量在主目标和XCTest目标之间的行为如何?下面是我看到的问题的一个例子:
设置代码
Manager.m
#import "Manager.h"
// This is the variable of interest!
static Manager *sharedManager = nil;
@implementation Manager
+ (instancetype)sharedManager
{
return sharedManager;
}
+ (void)setManager:(Manager *)manager
{
sharedManager = manager;
}
@end
下面是一个极其简单的ViewController
:
- (void)viewDidLoad {
[super viewDidLoad];
Manager *tempManager = [[Manager alloc] init];
[Manager setManager:tempManager];
}
混乱的实质
我正在尝试编写利用Manager
的xtest单元测试。问题是,根据代码的上下文,我在同一个代码执行流中看到了不同的Manager
实例。这对我来说是全新而怪异的。例如,考虑本单元测试:
- (void)testManager {
// 1
ViewController *vc = [[ViewController alloc] init];
// 2
NSLog(@"manager %@", [Manager sharedManager]);
Manager *tempManager = [[Manager alloc] init];
[Manager setManager:tempManager];
// 3
NSLog(@"manager %@", [Manager sharedManager]);
[vc viewDidLoad];
// 4
NSLog(@"manager %@", [Manager sharedManager]);
}
以下是一些观察到的行为:
po[Manager sharedManager]
我将看到一个具有内存地址的n对象实例。我假设这是因为ViewController
是项目情节提要的初始视图控制器,viewDidLoad()
创建并设置第一个Manager
共享实例[po Manager sharedManager]
将打印一个不同于这一行的NSLog的对象实例,但与在断点1处打印的实例相同viewDidLoad()
运行一个新的管理器
。用po
在这一行中断会显示一个新实例,但NSLog
会打印与3相同的实例NSLog
'd对象的内存地址与调试器po
'd对象不同。我不知道为什么。我猜这与XCTest如何在不同的“应用”实例中执行有关
我观察到的行为是,在相同的代码流中,.m文件中的静态
全局变量的访问取决于访问它的文件。为什么?
我在GitHub上发布了一个功能齐全的项目,演示了这一点:当我尝试在一个新项目中手动重新创建问题时,我得到了:
tempmanager
viewDidLoad
设置的管理器有两次出现Manager.m。每个都有自己的
sharedManager
静态变量副本。我对1感到惊讶。然而,为什么不实现通常的、线程安全的、经过良好测试的共享实例模式呢?好的一点,这是一个我必须在其中工作的约束的简化示例,这意味着我无法重构到适当的SingletonThreak@jon reid-这是一个关于目标成员身份的好发现,而且是有意的。基于此项目的第三方依赖关系是如何设置的,这是一个预先存在的条件,我需要弄清楚如何解决。我想这里的主要收获是,一个给定的实现文件不应该有多个目标的成员资格。我刚刚遇到了这个问题,更难找到的是没有日志,因为我的类是一个框架的成员和依赖于该框架的应用程序扩展。对于应用程序,Xcode控制台中有日志,但对于应用程序扩展没有日志。