RetainCycle 与 Globals
RetainCycle with Globals
假设 iOS 我们有:
在W2AppDelegate.m中:
GlobalViewController *globalVc;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
...
}
在SomeOtherViewController.m中:
- (void)viewDidLoad {
[super viewDidLoad];
[globalVc doSomething^{
[globalVc.someVariable doSomethingElse]; // Is there a retain cycle here?
}];
}
这里是否有循环引用,因为我们在块中有对 globalVc 的强引用。
globalVc -> 区块 -> globalVc
忽略糟糕的设计 - 视情况而定。
如果您在 ivar 中存储一个块,并且该块引用了 ivar 所在的对象,那么您确实会得到一个保留周期 - 见下文:
如果您实际上并没有存储该块,而只是调用该块,那么您最终可能根本不会使用任何额外的保留 - 见下文
不清楚您的 GlobalViewController
是单例还是可以更新的全局引用。如果它是一个单例,那么保留周期就不那么重要了,因为您希望该对象在程序的整个生命周期内都存在。
您已将 globalVc 变量定义为应用委托中的全局变量。当您创建 GlobalViewController
时,它将在您的应用程序的生命周期内持续存在。有时您希望视图控制器永远存在。
这不是一个保留周期,但它确实会在您的应用程序的生命周期内占用内存。
如果您仅将它用于执行块等任务,并且从不在屏幕上显示它的内容视图,您可能应该将 class 设为视图控制器以外的东西。
我有时会创建一个 Utils 单例,用于提供应用程序范围的实用程序功能。我写了一个访问函数,比如
+(Utils *) sharedUtils;
那个 returns 指向 Utils 单例的指针。这比像你这样使用全局更干净。
Is there a retain cycle here since we have a strong reference to globalVc inside the block.
没有。因为块只捕获局部变量。
[globalVc doSomething^{
[globalVc.someVariable doSomethingElse]; // Is there a retain cycle here?
}];
globalVc
未被块捕获,因为 globalVc
是全局变量。这里没有局部变量,所以块不捕获任何对象,因此块根本不保留任何对象。
假设 iOS 我们有:
在W2AppDelegate.m中:
GlobalViewController *globalVc; - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { ... }
在SomeOtherViewController.m中:
- (void)viewDidLoad { [super viewDidLoad]; [globalVc doSomething^{ [globalVc.someVariable doSomethingElse]; // Is there a retain cycle here? }]; }
这里是否有循环引用,因为我们在块中有对 globalVc 的强引用。
globalVc -> 区块 -> globalVc
忽略糟糕的设计 - 视情况而定。
如果您在 ivar 中存储一个块,并且该块引用了 ivar 所在的对象,那么您确实会得到一个保留周期 - 见下文:
如果您实际上并没有存储该块,而只是调用该块,那么您最终可能根本不会使用任何额外的保留 - 见下文
不清楚您的 GlobalViewController
是单例还是可以更新的全局引用。如果它是一个单例,那么保留周期就不那么重要了,因为您希望该对象在程序的整个生命周期内都存在。
您已将 globalVc 变量定义为应用委托中的全局变量。当您创建 GlobalViewController
时,它将在您的应用程序的生命周期内持续存在。有时您希望视图控制器永远存在。
这不是一个保留周期,但它确实会在您的应用程序的生命周期内占用内存。
如果您仅将它用于执行块等任务,并且从不在屏幕上显示它的内容视图,您可能应该将 class 设为视图控制器以外的东西。
我有时会创建一个 Utils 单例,用于提供应用程序范围的实用程序功能。我写了一个访问函数,比如
+(Utils *) sharedUtils;
那个 returns 指向 Utils 单例的指针。这比像你这样使用全局更干净。
Is there a retain cycle here since we have a strong reference to globalVc inside the block.
没有。因为块只捕获局部变量。
[globalVc doSomething^{
[globalVc.someVariable doSomethingElse]; // Is there a retain cycle here?
}];
globalVc
未被块捕获,因为 globalVc
是全局变量。这里没有局部变量,所以块不捕获任何对象,因此块根本不保留任何对象。