开发者

UITableView crashing when executing delegate

开发者 https://www.devze.com 2023-02-16 06:53 出处:网络
The code is below: @interface PreferenceViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> {

The code is below:

@interface PreferenceViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> {
    UITableView * preference;
    UISegmentedControl * dimension;
    NSArray * timeslot;
}

@property (nonatomic, retain) IBOutlet UITableView * preference;
@property (nonatomic, retain) IBOutlet UISegmentedControl * dimension;
@property (nonatomic, retain) NSArray * timeslot;

@end

- (void)viewDidLoad
{
    preference.delegate = self;
    preference.dataSource = self;
    timeslot = [NSArray arrayWithObjects:@"7:00-8:00", @"8:00-9:00", @"9:00-10:00", @"10:00-11:00", @"11:00-12:00", @"12:00-13:00", @"13:00-14:00", @"14:00-15:00", @"15:00-16:00", @"16:00-17:00", nil];
    NSLog(@"size of array is %d", [timeslot count]);
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

#pragma mark - Table View delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (dimension.selectedSegmentIndex == 0){
        return [timeslot count];
    }else
        return 15;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    //NSLog(@"TESTING");
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [t开发者_运维知识库ableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
    }
    // this is the MAGIC line!

    if (dimension.selectedSegmentIndex == 0)
        cell.text = [timeslot objectAtIndex:indexPath.row];

    return cell;
}

Was wondering what's causing the crash? It happens in that numberOfRowsInSection delegate and the call to timeslot count..


    timeslot = [NSArray arrayWithObjects:@"7:00-8:00", @"8:00-9:00", @"9:00-10:00", @"10:00-11:00", @"11:00-12:00", @"12:00-13:00", @"13:00-14:00", @"14:00-15:00", @"15:00-16:00", @"16:00-17:00", nil];

This line should have -retain.

timeslot = [[NSArray arrayWithObjects:@"7:00-8:00", @"8:00-9:00", @"9:00-10:00", @"10:00-11:00", @"11:00-12:00", @"12:00-13:00", @"13:00-14:00", @"14:00-15:00", @"15:00-16:00", @"16:00-17:00", nil] retain];

UPD -autorelease is not a good idea. You can only autorelease/release objects that you own. When you used -arrayWithObjects your object is owned by local AutoreleasePool.

Here is how it works in simple terms. Every time you create an object without -alloc or -copy methods it's autoreleased, which here means it will have reference count 1 until the end of the scope of the message. Techically autorelease pool business is asynchronous, so it may crash or may not, but you should assume this object is zombie at this point. So you must use -retain in order to preserve this object for another method's use. if you used explicitly -retain you must use -release explicitly when you are done with this object. So why not to use [[NSArray alloc] initWithObjects:...] right away. it's just more appropriate here. You can use retained property here too, but you don't want to expose internal variable when you don't have too.


In viewDidLoad, you are assigning the newly-created (and autoreleased) NSArray to the ivar rather than the property, which means that it is not retained for you. Thus, by the time it gets to tableView:numberOfRowsInSection: the array has been disposed of and you get EXC_BAD_ACCESS or a similar crash.

For this reason, I usually name my ivars _name rather than name to match the property. This does mean that the synthesize line must be the more complicated @synthesize name=_name, but it prevents accidentally assigning to the ivar rather than the property.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号