Ios 内存警告解除分配viewcontroller?

Ios 内存警告解除分配viewcontroller?,ios,memory-management,uiviewcontroller,didreceivememorywarning,Ios,Memory Management,Uiviewcontroller,Didreceivememorywarning,我有一个mainUIViewcontroller(vcMain),其中有两个UIViewcontroller子类。两个子类UIViewcontrollers(vcSub1/vcSub2)只显示一个图像和一些其他控件。vcSub1和vcSub2显示在UITabBarController中。 我实施了如下direceivememorywarning: vcMain: - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarnin

我有一个main
UIViewcontroller
(vcMain),其中有两个
UIViewcontroller
子类。两个子类
UIViewcontrollers
(vcSub1/vcSub2)只显示一个图像和一些其他控件。vcSub1和vcSub2显示在
UITabBarController
中。 我实施了如下
direceivememorywarning

vcMain:

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning]; 

    if ([self isViewLoaded] == NO) {
        // release the model, will be recreated in viewDidLoad
        [_brain release], self.brain = nil; 
    }
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];    

    if ([self isViewLoaded] == NO) {
        // will be recreated in viewDidLoad, only exists in vcSub1
        [self.zoomBrain release], [self setZoomBrain:nil];

        _button = nil; // autoreleased, created programmatically
    }
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning]; 

    if ([self isViewLoaded] == NO) {
        // nothing in here (yet)
    }
}
vcSub1:

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning]; 

    if ([self isViewLoaded] == NO) {
        // release the model, will be recreated in viewDidLoad
        [_brain release], self.brain = nil; 
    }
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];    

    if ([self isViewLoaded] == NO) {
        // will be recreated in viewDidLoad, only exists in vcSub1
        [self.zoomBrain release], [self setZoomBrain:nil];

        _button = nil; // autoreleased, created programmatically
    }
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning]; 

    if ([self isViewLoaded] == NO) {
        // nothing in here (yet)
    }
}
vcSub2:

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning]; 

    if ([self isViewLoaded] == NO) {
        // release the model, will be recreated in viewDidLoad
        [_brain release], self.brain = nil; 
    }
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];    

    if ([self isViewLoaded] == NO) {
        // will be recreated in viewDidLoad, only exists in vcSub1
        [self.zoomBrain release], [self setZoomBrain:nil];

        _button = nil; // autoreleased, created programmatically
    }
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning]; 

    if ([self isViewLoaded] == NO) {
        // nothing in here (yet)
    }
}
当我第一次模拟内存警告时,一切似乎都正常

Received simulated memory warning.
-[AppDelegate applicationDidReceiveMemoryWarning:] [Line 81] 
-[vcSub2 didReceiveMemoryWarning] [Line 102] 
-[vcMain didReceiveMemoryWarning] [Line 73] 
-[vcSub2 viewDidUnload] [Line 112] 
-[vcMain viewDidUnload] [Line 65] 
-[vcSub1 didReceiveMemoryWarning] [Line 150] 
-[vcMain didReceiveMemoryWarning] [Line 73] 
-[vcSub1 viewDidUnload] [Line 143] 
-[vcMain viewDidUnload] [Line 65] 
我可以一次又一次地这样做,没有问题。但是,如果我切换选项卡(从而重新加载视图)并再次模拟内存警告,我会得到以下结果:

Received simulated memory warning.
-[AppDelegate applicationDidReceiveMemoryWarning:] [Line 81] 
-[vcSub2 didReceiveMemoryWarning] [Line 102] 
-[vcMain didReceiveMemoryWarning] [Line 73] 
-[vcSub1 didReceiveMemoryWarning] [Line 150] 
-[vcMain didReceiveMemoryWarning] [Line 73] 
-[vcSub1 viewDidUnload] [Line 143] 
-[vcMain viewDidUnload] [Line 65] 
*** -[vcSub1 isViewLoaded]: message sent to deallocated instance 0x614de80
info malloc history 0x614de80
显示实例是vcSub1 viewcontroller

Alloc: Block address: 0x0614de80 length: 192
Stack - pthread: 0xa0425540 number of frames: 21
    0: 0x93f7f0a3 in malloc_zone_calloc
    1: 0x93f7effa in calloc
    2: 0x154a2d4 in class_createInstance
    3: 0x13165d8 in +[NSObject(NSObject) allocWithZone:]
    4: 0x13163da in +[NSObject(NSObject) alloc]
    5: 0x2bf0 in -[AppDelegate application:didFinishLaunchingWithOptions:] at AppDelegate.m:47
    6: 0x8dec89 in -[UIApplication _callInitializationDelegatesForURL:payload:suspended:]
    7: 0x8e0d88 in -[UIApplication  _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:]
    8: 0x8eb617 in -[UIApplication handleEvent:withNewEvent:]
    9: 0x8e3abf in -[UIApplication sendEvent:]
   10: 0x8e8f2e in _UIApplicationHandleEvent
   11: 0x30b9992 in PurpleEventCallback
   12: 0x13d3944 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__
   13: 0x1333cf7 in __CFRunLoopDoSource1
   14: 0x1330f83 in __CFRunLoopRun
   15: 0x1330840 in CFRunLoopRunSpecific
   16: 0x1330761 in CFRunLoopRunInMode
   17: 0x8e07d2 in -[UIApplication _run]
   18: 0x8ecc93 in UIApplicationMain
   19: 0x28f9 in main at main.m:14
   20: 0x2875 in start

我的vcSub1 viewcontroller解除分配的原因和方式?

我认为您释放对象的次数太多了。假设您的属性是(保留),那么您在这里有一个bug:

[self.zoomBrain release]
[self setZoomBrain:nil];
第一行将释放放大镜

第二行将释放zoomBrain,然后将其设置为nil

你释放它两次-你只需要第二行。如果使用setter方法(即setZoomBrain:),则它会自动为您释放上一个zoomBrain

这同样适用于:

[_brain release];
self.brain = nil; 
调用self.brain是另一种书写方式-再次,发布将被调用两次

在每种情况下,您只需要第二行:

self.brain = nil;

谢谢读了你的答案后,我做了更多的研究,现在我明白了;)