1

I have some problems with ARC. I'm trying to add multiples views to a ScrollView, and after that if the user tap one view will call a action.

But when user tap the view i get this message: "message sent to deallocated instance"

How can i retain the views?

this is my code in ViewController:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    int i;
    for (i=0;i<10;i++) {
        ChannelViewController *channelView = [[ChannelViewController alloc] init];
        [channelView.view setFrame:CGRectMake(i*175, 0, 175, 175)];
        //channelsScrollView is a ScrollView
        [self.channelsScrollView addSubview:channelView.view];
    }
    [self.channelsScrollView setContentSize:CGSizeMake(i*175, 175)];
}
Kazuki Sakamoto
  • 13,929
  • 2
  • 34
  • 96

1 Answers1

2

You need to hold reference to all ChannelViewController instances in your ViewController. In your code, after each for loop iteration, ARC releases your ChannelViewController instance. The simplest way to avoid this is to prepare an array property in ViewController.

// In ViewController.h
@property (nonatomic, retain) NSMutableArray * channelViews;

// In ViewController.m
@synthesize channelViews;

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.channelViews = [[NSMutableArray alloc] initWithCapacity:10];

    // Do any additional setup after loading the view from its nib.
    int i;
    for (i=0;i<10;i++) {
        ChannelViewController *channelView = [[ChannelViewController alloc] init];
        [channelView.view setFrame:CGRectMake(i*175, 0, 175, 175)];
        //channelsScrollView is a ScrollView
        [self.channelsScrollView addSubview:channelView.view];
        [self.channelViews addObject:channelView];     // <-- Add channelView to the array
    }
    [self.channelsScrollView setContentSize:CGSizeMake(i*175, 175)];
}
barley
  • 4,403
  • 25
  • 28
  • I'm seeing something similar, but I don't understand why this is necessary. Kazuki is calling `[self.channelsScrollView addSubview:channelView.view]`, so `self.channelsScrollView` now holds a reference to `channelView.view`. Does the UIView not hold a reference to its own controller? That seems weird. – Doug McBride Jan 02 '12 at 22:10
  • I don't know whether UIView internally holds a reference to its UIViewController, but even if it does, it should be a weak reference to avoid retain cycle. – barley Jan 03 '12 at 00:38
  • @barley But if there would be added many ChannelViewController objects to the array, then this can lead to app crash because of memory issues. Is there a better alternative? – iOS Dev Mar 20 '14 at 09:46
  • @Euroboy then you do not likely need to display all ChannelViewControllers at once, so would do some lazy loading based on visible area. That memory issue does not come from ARC, but from loading unnecessary objects. – barley Mar 20 '14 at 14:50