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

Posted

技术标签:

【中文标题】为测验应用程序创建工具栏【英文标题】:Create toolbar for quiz app 【发布时间】:2011-03-16 11:58:26 【问题描述】:

这与我之前发布的一个问题有关。我仍然坚持它。这里有一个描述。我正在创建一个测验应用程序。它有一个工具栏,每次用户单击按钮时都会动态创建其按钮。我使用一种方法将三个按钮添加到一个数组中,然后使用 for 循环检查问题的选项数量,然后为每个选项创建一个按钮并将其添加到数组中。后来我使用@987654321 @

添加按钮

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

我还有一个问题

有没有办法找出由 iphone sdk.Specificaly 中的内置方法创建的对象的保留计数,

1)NSMutableArray的addobject方法是否增加了被添加对象的retain count 2)如果我打算释放存储在其中的customBarButtonItem 对象,[[toolbar items] release] 是否可能会造成麻烦?

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

这是代码。它有很多注释行,这些都是我尝试过的选项 - (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)

// // [[工具栏项] 发布]; // [工具栏设置项目:临时项目动画:是]; //[物品发布]; //[self.view addSubview:toolbar]; if(isReviewing == FALSE && isPractice == FALSE)

    prevButton.enabled=FALSE;

//[toolbar bringSubviewToFront:customBarItem6.customView];

工具栏是通过 ib 创建的

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

【问题讨论】:

如果您不想要以前的问题或选项,您可以尝试从可变数组中删除它们。并请发布一些代码。 有一些 tempArray 的代码吗? 【参考方案1】:

我可以看到一些内存效率不是很高的东西:

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

基于此,我建议:

    使用 alloc/init 方法代替便捷构造函数 或者:在方法的开头创建NSAutoReleasePool,在结尾创建drain:这将释放所有自动释放的实体。

祝你好运

【讨论】:

我将 tempArray 作为类变量。现在仪器不显示任何泄漏。希望一切顺利 @mithun。您是在两次调用之间清空它还是继续向它添加对象而不释放它。它是否是类成员都没有关系。重要的是要添加到其中的所有对象都由数组保留。除非您释放数组中的所有项目或释放数组本身,否则您永远不会释放这些对象持有的内存。 在检查计数为 0 后,我在每次调用中使用 removeAllObjects 方法 @mithun。这应该适用于这个。另一个项目tempToolbar怎么样?您还应该在调用该方法时查看您的内存占用情况。内存使用量是否在增长?最后关于泄漏检测,您多久进行一次泄漏取样?最后一件事:您用于按钮的图像有多大? 图像为 4KB。我每 10 秒采样一次。根据我的理解,内存使用量没有增长。没有泄漏。每次激增后分配图下降到零。希望一切都好【参考方案2】:

很难遵循所有这些代码,但对于 1) 的简单部分答案是,是的,[NSMutableArray addObject:] 增加保留 +1。

【讨论】:

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

以上是关于为测验应用程序创建工具栏的主要内容,如果未能解决你的问题,请参考以下文章

自动为 Mysql 表行生成页面

如何创建一个测验应用 Flutter?

为测验应用程序选择啥云函数或数据库

C#单选按钮测验[重复]

Python实践练习:生成随机的测验试卷文件

JQuery 测验应用程序 - 突出显示无序列表条目和调用函数