为测验应用创建工具栏

时间:2011-03-16 11:58:27

标签: iphone ios uitoolbar

这与我之前发布的一个问题有关。我仍然坚持使用它。这是一个描述。我正在创建一个测验应用程序。它有一个工具栏,每次用户点击按钮时都会动态创建按钮。我使用一种方法在arrray中添加了三个按钮,然后使用for循环来检查问题的选择数量,然后为每个选择创建并添加一个按钮到数组。后来我使用了 [toolbar setitems:tempArray];

添加按钮


但在这样做时我遇到内存泄漏。应用程序在200个问题后崩溃。我发现使用仪器泄漏是在按钮创建区域。但是做了很多实验后我不知所措做。

我还有另一个问题

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

1)NSMutableArray的addobject方法是否会增加添加对象的保留计数 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)

// { // [[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];

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)

工具栏是通过ib

创建的

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

2 个答案:

答案 0 :(得分:1)

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

  1. 您使用了许多便利初始值设定项:buttonWithType和'imageNamed`。这些将在未来的某个时间点自行发布,但不在您的方法中。
  2. 项目tempToolbar已分配但从未发布。这会泄漏。
  3. 您的可变数组tempItems似乎也没有被释放:因为所有按钮都被添加到它中,这将完全杀死你...
  4. 基于此,我建议:

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

答案 1 :(得分:0)

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