为测验应用程序创建工具栏

发布于 2024-10-22 12:50:06 字数 5277 浏览 4 评论 0原文

这与我之前发布的一个问题有关。我仍然坚持不下去。这是一个描述。我正在创建一个测验应用程序。它有一个工具栏,每次用户单击按钮时都会动态创建其按钮。我做到了使用一种方法将三个按钮添加到数组中,然后使用 for 循环检查问题的选择数量,然后为每个选择创建一个按钮并将其添加到数组中。稍后我使用
<代码> [工具栏设置项:tempArray];

添加按钮


但是在执行此操作时,我遇到了内存泄漏。该应用程序在 200 个问题后崩溃。我使用仪器发现泄漏位于按钮创建区域。但是在做了很多实验之后,我在不知道该做什么。

我还有另一个问题有

没有办法找出iphone sdk中内置方法创建的对象的保留计数。具体来说,

1)NSMutableArray的addobject方法是否会增加添加对象的保留计数 2)如果我打算释放存储在其中的customBarButtonItem对象,[[工具栏项目]释放]是否可能会造成麻烦?

因为在使用这些选项时,应用程序要么立即崩溃,要么更改对报告的泄漏没有影响,

这是代码。它有很多注释行,这是我尝试过的选项
<代码> - (void)CreateButtons{

      UIToolbar *tempToolBar=[[UIToolbar alloc] ]
      numberOfChoices=0;//set number of choice buttons at present to 0
      NSMutableArray *tempItems=[[NSMutableArray alloc] init];//Array for holding the buttons
      Question *question=[currentQuestion question];
      NSString *answer=[question answerOptions];
int numericAnswer=0;
numericAnswer=[answer characterAtIndex:0];  
//see if its a number or a character
if (numericAnswer > 96) { // its a character
    int choice;
    for (choice=97; choice <=numericAnswer ; choice ++) {

        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        [button setBackgroundImage:[UIImage imageNamed:@"gembtnblu.png"] forState:UIControlStateNormal];
        button.frame = CGRectMake(0, 0, TOOLBAR_BUTTON_WIDTH , TOOLBAR_BUTTON_HEIGHT);
        [button setTitle:[NSString stringWithFormat:@"%c",(char)choice] forState:UIControlStateNormal];
        [button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
        [button addTarget:self action:@selector(ChoiceButtonTouched:) forControlEvents:UIControlEventTouchUpInside];
        [button setTag:choice];
        UIBarButtonItem *customBarItem = [[UIBarButtonItem alloc] initWithCustomView:button];

        if (isReviewing == TRUE) {
            customBarItem.customView.userInteractionEnabled=FALSE;
        }
        //Add button to the array
        [tempItems addObject:customBarItem];
        //release buttons
        [customBarItem release];
        numberOfChoices++;
    }
}
else {

    int choice;
    for (choice=49; choice<=numericAnswer; choice ++) {

        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        [button setBackgroundImage:[UIImage imageNamed:@"gembtnblu.png"] forState:UIControlStateNormal];
        button.frame = CGRectMake(0, 0, TOOLBAR_BUTTON_WIDTH , TOOLBAR_BUTTON_HEIGHT);
        [button setTitle:[NSString stringWithFormat:@"%c",choice] forState:UIControlStateNormal];
        [button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
        [button addTarget:self action:@selector(ChoiceButtonTouched:) forControlEvents:UIControlEventTouchUpInside];
        [button setTag:choice];
        UIBarButtonItem *customBarItem = [[UIBarButtonItem alloc] initWithCustomView:button];

        //Add button to the array
        [tempItems addObject:customBarItem];

        if (isReviewing == TRUE) {
            customBarItem.customView.userInteractionEnabled=FALSE;
        }
        //release buttons
        [customBarItem release];

        numberOfChoices++;
    }
}

//load the image

UIButton *previousButton = [UIButton buttonWithType:UIButtonTypeCustom];
[previousButton setBackgroundImage:[UIImage imageNamed:@"prev.png"] forState:UIControlStateNormal];
[previousButton addTarget:self action:@selector(PreviousClicked:) forControlEvents:UIControlEventTouchUpInside];
previousButton.frame = CGRectMake(0, 0, TOOLBAR_BUTTON_WIDTH , TOOLBAR_BUTTON_HEIGHT);
UIBarButtonItem *customBarItem6 = [[UIBarButtonItem alloc] initWithCustomView:previousButton];
//[previousButton release];
self.prevButton=customBarItem6;

UIButton *nextButton= [UIButton buttonWithType:UIButtonTypeCustom];
[nextButton setBackgroundImage:[UIImage imageNamed:@"nex.png"] forState:UIControlStateNormal];
[nextButton addTarget:self action:@selector(nextClicked:) forControlEvents:UIControlEventTouchUpInside];
nextButton.frame = CGRectMake(0, 0, TOOLBAR_BUTTON_WIDTH, TOOLBAR_BUTTON_HEIGHT);
UIBarButtonItem *customBarItem7 = [[UIBarButtonItem alloc] initWithCustomView:nextButton];
//[nextButton release];
//Use this to put space in between your toolbox buttons
UIBarButtonItem *flexItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];

[tempItems addObject:flexItem];
[tempItems addObject:customBarItem6];
[tempItems addObject:customBarItem7];

//release buttons
[customBarItem6 release];
[customBarItem7 release];
[flexItem release];

//NSArray *items=[[NSArray alloc] initWithArray:(NSArray *)tempItems];
//[tempItems release];

//add array of buttons to toolbar
//if([[toolbar items] count]>0)

// { // [[工具栏项目]释放]; // } [工具栏 setItems:tempItems 动画:YES]; //[物品发布]; //[self.view addSubview:工具栏]; if(isReviewing == FALSE &&isPractice == FALSE) {

    prevButton.enabled=FALSE;
}
//[toolbar bringSubviewToFront:customBarItem6.customView];

}

工具栏是通过 ib 创建的

是的,它有很多代码,但它只是根据问题的选择数量创建按钮。两个 for 循环类似,除了一个将 a、b、c、d 放在按钮上,而另一种则放置 1,2,3,4.....此外还创建了三个按钮。一个用于下一个、上一个和弹性项目。每次用户单击下一个按钮时都会调用此方法。

This is related to a question i posted earlier.I am still stuck on it.Heres a description.I am creating a quiz app.It has a toolbar whose buttons are to be created dynamicaly each time the user clicks a button.I did it using a method which adds three buttons into an arrray, then uses a for loop to check the number of choices the question has and then create and add a button to the array for each choice.Later i use

[toolbar setitems:tempArray];

to add the buttons

But while doing this i am running into memory leaks.The app crashes after 200 questions.I found using instruments that the leaks were in button creation area.But after doing many experiments im at a loss about what to do.

I also have another question

Is there a way to find out the retain count of objects created by built in methods in iphone sdk.Specificaly,

1)Does NSMutableArray's addobject method increase the retain count of the added object
2)Is [[toolbar items] release] likely to cause trouble if i am intending to release the customBarButtonItem objects stored in it?

because wile playing with these options , the app either crashes immediately or the changes have no effect on the reported leaks

heres the code.Its got a lot of comment lines which are options i tried

- (void)CreateButtons{

      UIToolbar *tempToolBar=[[UIToolbar alloc] ]
      numberOfChoices=0;//set number of choice buttons at present to 0
      NSMutableArray *tempItems=[[NSMutableArray alloc] init];//Array for holding the buttons
      Question *question=[currentQuestion question];
      NSString *answer=[question answerOptions];
int numericAnswer=0;
numericAnswer=[answer characterAtIndex:0];  
//see if its a number or a character
if (numericAnswer > 96) { // its a character
    int choice;
    for (choice=97; choice <=numericAnswer ; choice ++) {

        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        [button setBackgroundImage:[UIImage imageNamed:@"gembtnblu.png"] forState:UIControlStateNormal];
        button.frame = CGRectMake(0, 0, TOOLBAR_BUTTON_WIDTH , TOOLBAR_BUTTON_HEIGHT);
        [button setTitle:[NSString stringWithFormat:@"%c",(char)choice] forState:UIControlStateNormal];
        [button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
        [button addTarget:self action:@selector(ChoiceButtonTouched:) forControlEvents:UIControlEventTouchUpInside];
        [button setTag:choice];
        UIBarButtonItem *customBarItem = [[UIBarButtonItem alloc] initWithCustomView:button];

        if (isReviewing == TRUE) {
            customBarItem.customView.userInteractionEnabled=FALSE;
        }
        //Add button to the array
        [tempItems addObject:customBarItem];
        //release buttons
        [customBarItem release];
        numberOfChoices++;
    }
}
else {

    int choice;
    for (choice=49; choice<=numericAnswer; choice ++) {

        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        [button setBackgroundImage:[UIImage imageNamed:@"gembtnblu.png"] forState:UIControlStateNormal];
        button.frame = CGRectMake(0, 0, TOOLBAR_BUTTON_WIDTH , TOOLBAR_BUTTON_HEIGHT);
        [button setTitle:[NSString stringWithFormat:@"%c",choice] forState:UIControlStateNormal];
        [button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
        [button addTarget:self action:@selector(ChoiceButtonTouched:) forControlEvents:UIControlEventTouchUpInside];
        [button setTag:choice];
        UIBarButtonItem *customBarItem = [[UIBarButtonItem alloc] initWithCustomView:button];

        //Add button to the array
        [tempItems addObject:customBarItem];

        if (isReviewing == TRUE) {
            customBarItem.customView.userInteractionEnabled=FALSE;
        }
        //release buttons
        [customBarItem release];

        numberOfChoices++;
    }
}

//load the image

UIButton *previousButton = [UIButton buttonWithType:UIButtonTypeCustom];
[previousButton setBackgroundImage:[UIImage imageNamed:@"prev.png"] forState:UIControlStateNormal];
[previousButton addTarget:self action:@selector(PreviousClicked:) forControlEvents:UIControlEventTouchUpInside];
previousButton.frame = CGRectMake(0, 0, TOOLBAR_BUTTON_WIDTH , TOOLBAR_BUTTON_HEIGHT);
UIBarButtonItem *customBarItem6 = [[UIBarButtonItem alloc] initWithCustomView:previousButton];
//[previousButton release];
self.prevButton=customBarItem6;

UIButton *nextButton= [UIButton buttonWithType:UIButtonTypeCustom];
[nextButton setBackgroundImage:[UIImage imageNamed:@"nex.png"] forState:UIControlStateNormal];
[nextButton addTarget:self action:@selector(nextClicked:) forControlEvents:UIControlEventTouchUpInside];
nextButton.frame = CGRectMake(0, 0, TOOLBAR_BUTTON_WIDTH, TOOLBAR_BUTTON_HEIGHT);
UIBarButtonItem *customBarItem7 = [[UIBarButtonItem alloc] initWithCustomView:nextButton];
//[nextButton release];
//Use this to put space in between your toolbox buttons
UIBarButtonItem *flexItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];

[tempItems addObject:flexItem];
[tempItems addObject:customBarItem6];
[tempItems addObject:customBarItem7];

//release buttons
[customBarItem6 release];
[customBarItem7 release];
[flexItem release];

//NSArray *items=[[NSArray alloc] initWithArray:(NSArray *)tempItems];
//[tempItems release];

//add array of buttons to toolbar
//if([[toolbar items] count]>0)

// {
// [[toolbar items] release];
// }
[toolbar setItems:tempItems animated:YES];
//[items release];
//[self.view addSubview:toolbar];
if(isReviewing == FALSE && isPractice == FALSE) {

    prevButton.enabled=FALSE;
}
//[toolbar bringSubviewToFront:customBarItem6.customView];

}

toolbar is created via ib

Yeah its a lot of code but it just creates buttons based on number of choices for a question.The two for loops are similar exept one puts a,b,c,d on the buttons while the other one puts 1,2,3,4.....In addition three buttons are created.One for next, previous and a flex item .This method is is called each time the user clicks teh next button.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

笨笨の傻瓜 2024-10-29 12:50:06

我可以看到一些在内存方面效率不高的事情:

  1. 您使用了很多方便的初始化程序:buttonWithType 和 'imageNamed`。这些将在未来的某个时刻自动释放,但不会在您的方法内。
  2. tempToolbar 项已分配但从未释放。这会泄漏。
  3. 您的可变数组 tempItems 似乎也没有被释放:这将彻底杀死您,因为所有按钮都添加到其中...

基于此,我建议:

  1. 使用 alloc/init 方法而不是便利构造函数
  2. 或者:在方法开始处创建一个 NSAutoReleasePool 并在最后耗尽它:这将释放所有自动释放的实体。

祝你好运

I can see a few things which are not very efficient memory-wise:

  1. You use lots of convenience initializers: buttonWithType and 'imageNamed`. These will autorelease themselves at some point in the future but not within your method.
  2. The item tempToolbar is allocated but never released. This will leak.
  3. Your mutable array tempItems also does not appear to be released: this will kill you completely since all your buttons are added to it...

Based on this I would suggest:

  1. Use of alloc/init methods instead of convenience constructors
  2. Alternatively: create an NSAutoReleasePool at the start of your method and drain it at the end: this will release all autoreleased entities.

Good luck

顾铮苏瑾 2024-10-29 12:50:06

很难理解所有这些代码,但是 1) 的一个简单的部分答案是,是的,[NSMutableArray addObject:] 增加了保留+1。

Difficult to follow all that code, but an easy part-answer to 1) is that, yes, [NSMutableArray addObject:] increase retain +1.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文