我试图创建一个类集群作为UIViewController
的子类来完成一些点:
1。 ViewController的不同行为取决于实际的iOS版本
2。 iOS版本检查不会使代码混乱
3。调用者不需要关心
到目前为止,我得到了MyViewController
, MyViewController_iOS7
和MyViewController_Legacy
班。
创建实例,我调用myViewControllerWithStuff:(StuffClass*)stuff
方法,实现如下:
+(id)myViewControllerWithStuff:(StuffClass*)stuff
{
if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1)
{
return [[MyViewController_iOS7 alloc] initWithStuff:stuff];
}
else
{
return [[MyViewController_Legacy alloc] initWithStuff:stuff];
}
}
调用方使用myViewControllerWithStuff:
。之后,这样创建的视图控制器被推送到UINavigationController
的导航堆栈。
这几乎像预期的那样工作,但有一个很大的缺点:当MyViewController_xxx
从导航堆栈中弹出时,ARC不会释放它的实例。不管哪个iOS版本。
我错过了什么?
更新: -initWithStuff:
-(id)initWithStuff:(StuffClass*)stuff
{
if (self = [super init])
{
self.stuff = stuff;
}
return self;
}
此方法也在MyViewController
中实现。差异会在稍后出现(例如viewDidLoad:
)。
首先:感谢大家的帮助、评论、回答、建议……
当然还有另一个strong
对MyViewController
对象的引用。但它不是那么明显,因为它不是属性或实例变量。
在viewDidLoad
中,我做了以下操作:
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillResignActiveNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
[self saveState];
}];
这样可以防止用户将应用程序发送到后台时数据丢失。当然,块捕获其环境中所需的部分。在本例中,它捕获了self
。该块保持self
存活,直到它(该块)被销毁,这就是[[NSNotificationCenter defaultCenter] removeObserver:self];
被调用时的情况。但是,不幸的是,这个调用被放置在MyViewController
的dealloc
方法中,只要块存在就不会被调用…
修复如下:
__weak MyViewController *weakSelf = self;
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillResignActiveNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
[weakSelf saveState];
}];
现在块捕获weakSelf
。这样,它就不能保持MyViewController
-对象的活动,所有的东西都可以正常工作。