Search code examples
iosobjective-ccocoamemory-managementretain

Custom object of same type added multiple times inside for loop


I am allocating custom object (viewcontroller in this case) inside for- loop. And everything seems to work fine. But when I tap on the button of first custom object of viewcontroller, the application crashes. It is because the instance for the custom object is not retained. Although it works fine for the last added object. Please advice.

    dispatch_async(dispatch_get_main_queue(), ^{
        NSInteger index = 0;
        for (TestStep *obj_Teststep in objTestSuite.testSteps) {
            TestStepView * obj_TestStepView = [[TestStepView alloc] initWithNibName:@"TestStepView" bundle:[NSBundle mainBundle]];
            obj_TestStepView.testStep = obj_Teststep;
            obj_TestStepView.delegate = self;
            DMPaletteSectionView *sectionView = [[DMPaletteSectionView alloc] initWithContentView:obj_TestStepView.view andTitle:[NSString stringWithFormat:@"Test Step %@ - %@",obj_Teststep.executionOrder,obj_Teststep.apiCallPath] initialState:DMPaletteStateCollapsed withAction:YES andIndex:index];
            sectionView.layer.backgroundColor = [NSColor redColor].CGColor;
            [sectionArray addObject:sectionView];
            index++;
        }
        [sectionArray addObject:[[DMPaletteSectionView alloc] initWithContentView:self.addNewTestStepView andTitle:@"Add Test Step" initialState:DMPaletteStateExpanded withAction:NO andIndex:0]];
        container.sectionViews = sectionArray;

        for (int i =0; i<container.sectionViews.count; i++) {
            DMPaletteSectionView *dmobj = [container.sectionViews objectAtIndex:i];
            dmobj.delegate = self;
        }
    });

Solution

  • As @trojanfoe says, your design is faulty. You can't create a view controller and add it's view to another view controller without maintaining a strong reference to the view controller.

    You create a bunch of TestStepView objects (which I assume are view CONTROLLERS?) Then you pass the view of those objects to a DMPaletteSectionView, but never retain a strong reference to the TestStepView object. That won't work.

    When you add a view controller's view to another view controller you should use the parent/child view controller support that was added to iOS (in iOS 5, if I remember correctly.) Do a search in the Xcode docs in the UIViewController class reference for the words "parent" and "child". There are a family of methods that let you set that up.

    You would need to make your TestStepView (view controller?) a child of the DMPaletteSectionView (view controller?)

    BTW, stop calling view controllers views, both in your question and in your code. View objects and view controller objects are totally different, and you will confuse both yourself and your readers by calling view controllers views.

    I use the abbreviation VC for view controllers in my code to keep my class names shorter, while keeping it clear that they are view controllers, not views.