【问题标题】:Why do I have memory problems?为什么我有记忆问题?
【发布时间】:2011-02-03 18:34:16
【问题描述】:

我从 XCode 收到此错误:

objc[8422]: FREED(id): message release sent to freed object=0x3b120c0

我google了一下,发现和内存有关。但我不知道哪行代码出错了,有什么想法吗?在模拟器中启动我的应用程序后,它提示一秒钟,然后除了上述错误之外没有其他错误。

@implementation MyAppDelegate

@synthesize window;
@synthesize viewController;


- (void)applicationDidFinishLaunching:(UIApplication *)application {    

    // Override point for customization after app launch    
    [window addSubview:viewController.view];
    [window makeKeyAndVisible];

    [self changeScene:[MainGameMenuScene class]];
}


- (void)dealloc {
    [viewController release];
    [window release];
    [super dealloc];
}

- (void) changeScene: (Class) scene
{
    BOOL animateTransition = true;

    if(animateTransition){
        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDuration:0.5];
        [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:window cache:YES]; //does nothing without this line.
    }

    if( viewController.view != nil ) {
        [viewController.view removeFromSuperview]; //remove view from window's subviews.
        [viewController.view release]; //release gamestate 
    }

    viewController.view = [[scene alloc] initWithFrame:CGRectMake(0, 0, IPHONE_WIDTH, IPHONE_HEIGHT) andManager:self];

        //now set our view as visible
    [window addSubview:viewController.view];
    [window makeKeyAndVisible];

    if(animateTransition){
        [UIView commitAnimations];  
    }   
}

【问题讨论】:

    标签: objective-c xcode debugging iphone-sdk-3.0 ios-simulator


    【解决方案1】:
    [viewController.view release]; //release gamestate
    

    这是一个额外的释放(如果你没有分配它,就不要释放它)。下面几行:

    viewController.view = [[scene alloc] initWithFrame:CGRectMake(0, 0, IPHONE_WIDTH, IPHONE_HEIGHT) andManager:self]; 
    

    将在保留新值之前再次释放 viewController.view,这将过度释放视图并导致崩溃(它将释放消息发送到已被释放的对象/已释放的内存) .相反,请尝试:

    scene *view = [[scene alloc] initWithFrame:CGRectMake(0, 0, IPHONE_WIDTH, IPHONE_HEIGHT) andManager:self];
    viewController.view = view; // setView will release the old/retain the new
    [view release];             // so you don't need to worry about releasing it later
    

    【讨论】:

    • 我可以在 removeFromSuperview 之前保留 controller.view 吗?
    • 不应该保留或释放它——尤其是当你要用新分配的视图替换它时。
    【解决方案2】:

    找到解决办法:

    - (void) changeScene: (Class) scene
    {
        BOOL animateTransition = true;
    
        if(animateTransition){
            [UIView beginAnimations:nil context:NULL];
            [UIView setAnimationDuration:0.5];
            [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:window cache:YES]; //does nothing without this line.
        }
    
        if( viewController.view != nil ) {
            [viewController.view retain]; //retain the view.
            [viewController.view removeFromSuperview]; //remove view from window's subviews.
            [viewController.view release]; //release gamestate 
        }
    
        viewController.view = [[scene alloc] initWithFrame:CGRectMake(0, 0, IPHONE_WIDTH, IPHONE_HEIGHT) andManager:self];
    
            //now set our view as visible
        [window addSubview:viewController.view];
        [window makeKeyAndVisible];
    
        if(animateTransition){
            [UIView commitAnimations];  
        }   
    }
    

    它需要我保留视图,但我不知道为什么这是必要的。

    【讨论】:

    • 这完全没有必要。你不应该首先释放视图,因为它是另一个对象的属性。
    • 但是我可以重复使用这种方法来改变场景,我应该保持这种方式吗?
    【解决方案3】:

    这一行:

    [viewController.view release];
    

    很可能是您的问题。除非在类的 dealloc 方法中,否则永远不要向对象的属性发送释放。视图控制器视图属性访问器将为您处理保留和释放。

    【讨论】:

      猜你喜欢
      • 2011-07-24
      • 1970-01-01
      • 2021-04-23
      • 2019-12-26
      • 2023-02-04
      • 1970-01-01
      • 2019-06-13
      • 2014-11-14
      • 2018-11-06
      相关资源
      最近更新 更多