消息发送到解除分配的实例

时间:2012-08-27 16:49:51

标签: objective-c memory nsmutablearray memory-management

我正试图在我的程序中排序内存问题。

我的程序停在了一行:

 label.text = [[[[self.allData objectAtIndex:indexPath.row-1]objectAtIndex:1+[[self.measurments objectAtIndex:(i-1)]intValue]]objectAtIndex:1]stringValue];

whit mesage:

 Thread 1: EXC_BREAKPOINT 
 ** -[CFNumber stringValue]: message sent to deallocated instance 0x859add0

我拥有allData和measurments的属性

@property (nonatomic, retain) NSMutableArray *allData;
@property (nonatomic, retain) NSMutableArray *measurments;

我将allData定义为:

self.allData = [[[NSMutableArray alloc] init]autorelease];

self.allData = [self GetTableOfLevel:TableLevel section:TableSection perent:0 array:self._backupData];

其中GetTableOfLevel:TableLevel函数返回NSMutableArray。

之后我将allData保留原样,除非我将其复制为:

self.backupData = [[self.allData copy]autorelease];

有任何人知道它可能出错吗?


我尝试了建议并切换到ARC,但我有一些问题,下载了一些库。

我有SBTableAlert,它看起来像:

    //
//  --------------------------------------------
//  Copyright (C) 2011 by Simon Blommegård
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//  --------------------------------------------
//
//  SBTableAlert.h
//  SBTableAlert
//
//  Created by Simon Blommegård on 2011-04-08.
//  Copyright 2011 Simon Blommegård. All rights reserved.
//

#import <Foundation/Foundation.h>

#define kTableCornerRadius 5.

typedef enum {
    SBTableAlertTypeSingleSelect, // dismiss alert with button index -1 and animated (default)
    SBTableAlertTypeMultipleSelct, // dismiss handled by user eg. [alert.view dismiss...];
} SBTableAlertType;

typedef enum {
    SBTableAlertStylePlain, // plain white BG and clear FG (default)
    SBTableAlertStyleApple, // same style as apple in the alertView for slecting wifi-network (Use SBTableAlertCell)
} SBTableAlertStyle;

// use this class if you would like to use the custom section headers by yourself
@interface SBTableViewSectionHeaderView : UIView {}
@property (nonatomic, copy) NSString *title;
@end

@interface SBTableAlertCell : UITableViewCell {}
- (void)drawCellBackgroundView:(CGRect)r;
@end

@class SBTableAlert;

@protocol SBTableAlertDelegate <NSObject>
@optional

- (CGFloat)tableAlert:(SBTableAlert *)tableAlert heightForRowAtIndexPath:(NSIndexPath *)indexPath;

- (void)tableAlert:(SBTableAlert *)tableAlert didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
- (void)tableAlertCancel:(SBTableAlert *)tableAlert;

- (void)tableAlert:(SBTableAlert *)tableAlert clickedButtonAtIndex:(NSInteger)buttonIndex;

- (void)willPresentTableAlert:(SBTableAlert *)tableAlert;
- (void)didPresentTableAlert:(SBTableAlert *)tableAlert;

- (void)tableAlert:(SBTableAlert *)tableAlert willDismissWithButtonIndex:(NSInteger)buttonIndex;
- (void)tableAlert:(SBTableAlert *)tableAlert didDismissWithButtonIndex:(NSInteger)buttonIndex;

@end

@protocol SBTableAlertDataSource <NSObject>
@required

- (UITableViewCell *)tableAlert:(SBTableAlert *)tableAlert cellForRowAtIndexPath:(NSIndexPath *)indexPath;
- (NSInteger)tableAlert:(SBTableAlert *)tableAlert numberOfRowsInSection:(NSInteger)section;

@optional

- (NSInteger)numberOfSectionsInTableAlert:(SBTableAlert *)tableAlert; // default 1
- (NSString *)tableAlert:(SBTableAlert *)tableAlert titleForHeaderInSection:(NSInteger)section;

@end

@interface SBTableAlert : NSObject <UITableViewDelegate, UITableViewDataSource, UIAlertViewDelegate> {}

@property (nonatomic, retain) UIAlertView *view;
@property (nonatomic, retain) UITableView *tableView;
@property (nonatomic) SBTableAlertType type;
@property (nonatomic) SBTableAlertStyle style;
@property (nonatomic) NSInteger maximumVisibleRows; // default 4, (nice in both orientations w/ rowHeigh == 40), if -1 is passed it will display the whole table.
@property (nonatomic) CGFloat rowHeight; // default 40, (default in UITableView == 44)

@property (nonatomic, assign) id <SBTableAlertDelegate> delegate;
@property (nonatomic, assign) id <SBTableAlertDataSource> dataSource;

@property (nonatomic, assign) id <UITableViewDelegate> tableViewDelegate; // default self, (set other for more advanded use)
@property (nonatomic, assign) id <UITableViewDataSource> tableViewDataSource; // default self, (set other for more advanded use)
@property (nonatomic, assign) id <UIAlertViewDelegate> alertViewDelegate; // default self, (set other for more advanded use)

- (id)initWithTitle:(NSString *)title cancelButtonTitle:(NSString *)cancelTitle messageFormat:(NSString *)message, ...;
+ (id)alertWithTitle:(NSString *)title cancelButtonTitle:(NSString *)cancelTitle messageFormat:(NSString *)message, ...;

- (void)show;

@end


    //
//  --------------------------------------------
//  Copyright (C) 2011 by Simon Blommegård
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//  --------------------------------------------
//
//  SBTableAlert.m
//  SBTableAlert
//
//  Created by Simon Blommegård on 2011-04-08.
//  Copyright 2011 Simon Blommegård. All rights reserved.
//

#import "SBTableAlert.h"
#import <QuartzCore/QuartzCore.h>

@interface SBTableViewTopShadowView : UIView {}
@end

@implementation SBTableViewTopShadowView

- (void)drawRect:(CGRect)rect {
    [super drawRect:rect];

    CGContextRef context = UIGraphicsGetCurrentContext();

    // Draw top shadow
    CGFloat colors [] = { 
        0, 0, 0, 0.4,
        0, 0, 0, 0,
    };

    CGColorSpaceRef baseSpace = CGColorSpaceCreateDeviceRGB();
    CGGradientRef gradient = CGGradientCreateWithColorComponents(baseSpace, colors, NULL, 2);
    CGColorSpaceRelease(baseSpace), baseSpace = NULL;

    CGPoint startPoint = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMinY(self.bounds));
    CGPoint endPoint = CGPointMake(CGRectGetMidX(self.bounds), 8);

    CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
    CGGradientRelease(gradient), gradient = NULL;
}

@end

@interface SBTableView : UITableView {}
@property (nonatomic) SBTableAlertStyle alertStyle;
@end

@implementation SBTableView

@synthesize alertStyle=_alertStyle;

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();

    if (_alertStyle == SBTableAlertStyleApple) {
        // Draw background gradient
        CGFloat colors [] = { 
            0.922, 0.925, 0.933, 1,
            0.749, 0.753, 0.761, 1,
        };

        CGColorSpaceRef baseSpace = CGColorSpaceCreateDeviceRGB();
        CGGradientRef gradient = CGGradientCreateWithColorComponents(baseSpace, colors, NULL, 2);
        CGColorSpaceRelease(baseSpace), baseSpace = NULL;

        CGPoint startPoint = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMinY(self.bounds));
        CGPoint endPoint = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMaxY(self.bounds));

        CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
        CGGradientRelease(gradient), gradient = NULL;
    }

    [super drawRect:rect];
}

@end

@interface SBTableAlertCellBackgroundView : UIView
@end

@implementation SBTableAlertCellBackgroundView

- (void)drawRect:(CGRect)r {
    [(SBTableAlertCell *)[self superview] drawCellBackgroundView:r];
}

@end

@implementation SBTableViewSectionHeaderView
@synthesize title=_title;

- (id)initWithTitle:(NSString *)title {
    if ((self = [super initWithFrame:CGRectZero])) {
        [self setTitle:title];
        [self setBackgroundColor:[UIColor colorWithRed:0.165 green:0.224 blue:0.376 alpha:0.85]];
    }

    return self;
}

- (void)dealloc {
    [self setTitle:nil];
    [super dealloc];
}

- (void)drawRect:(CGRect)rect {
    [super drawRect:rect];

    CGContextRef context = UIGraphicsGetCurrentContext();

    [[UIColor colorWithWhite:0 alpha:0.8] set];
    [_title drawAtPoint:CGPointMake(10, 4) withFont:[UIFont boldSystemFontOfSize:12]];  
    [[UIColor whiteColor] set];
    [_title drawAtPoint:CGPointMake(10, 5) withFont:[UIFont boldSystemFontOfSize:12]];

    CGContextSetLineWidth(context, 1.5);

    [[UIColor colorWithWhite:1 alpha:0.35] set];
    CGContextMoveToPoint(context, 0, 0);
    CGContextAddLineToPoint(context, self.bounds.size.width, 0);
    CGContextStrokePath(context);

    [[UIColor colorWithWhite:0 alpha:0.35] set];
    CGContextMoveToPoint(context, 0, self.bounds.size.height);
    CGContextAddLineToPoint(context, self.bounds.size.width, self.bounds.size.height);
    CGContextStrokePath(context);
}

@end

@interface SBTableAlertCell ()
@property (nonatomic, retain) SBTableAlertCellBackgroundView *cellBackgroundView;
@end

@implementation SBTableAlertCell
@synthesize cellBackgroundView = _cellBackgroundView;

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
    if((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) {
        CGRect frame = CGRectMake(0.0, 0.0, self.contentView.bounds.size.width, self.contentView.bounds.size.height);

        _cellBackgroundView = [[SBTableAlertCellBackgroundView alloc] initWithFrame:frame];
        [_cellBackgroundView setBackgroundColor:[UIColor clearColor]];
        [_cellBackgroundView setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)];
        [self setBackgroundView:_cellBackgroundView];
        [_cellBackgroundView release];

        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(setNeedsDisplay) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
    }
    return self;
}

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [super dealloc];
}

- (void)layoutSubviews {
    [super layoutSubviews];

    float editingOffset = 0.;
    if (self.editing)
        editingOffset = -self.contentView.frame.origin.x;

    _cellBackgroundView.frame = CGRectMake(editingOffset,
                                                                            _cellBackgroundView.frame.origin.y,
                                                                            self.frame.size.width - editingOffset,
                                                                            _cellBackgroundView.frame.size.height);

    [self.textLabel setBackgroundColor:[UIColor clearColor]];
    [self.detailTextLabel setBackgroundColor:[UIColor clearColor]];
    [self setBackgroundColor:[UIColor clearColor]];

    [self setNeedsDisplay];
}

- (void)setNeedsDisplay {
    [super setNeedsDisplay];
    [_cellBackgroundView setNeedsDisplay];
}

- (void)drawCellBackgroundView:(CGRect)r {
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(context, 1.5);

    [[UIColor colorWithWhite:1 alpha:0.8] set];
    CGContextMoveToPoint(context, 0, 0);
    CGContextAddLineToPoint(context, self.bounds.size.width, 0);
    CGContextStrokePath(context);

    [[UIColor colorWithWhite:0 alpha:0.35] set];
    CGContextMoveToPoint(context, 0, self.bounds.size.height);
    CGContextAddLineToPoint(context, self.bounds.size.width, self.bounds.size.height);
    CGContextStrokePath(context);
}

@end

@interface SBTableAlert ()
@property (nonatomic, retain) SBTableViewTopShadowView *shadow;
@property (nonatomic, assign) BOOL presented;

- (id)initWithTitle:(NSString *)title cancelButtonTitle:(NSString *)cancelTitle messageFormat:(NSString *)format args:(va_list)args;
- (void)increaseHeightBy:(CGFloat)delta;
- (void)layout;

@end

@implementation SBTableAlert

@synthesize view=_alertView;
@synthesize tableView=_tableView;
@synthesize type=_type;
@synthesize style=_style;
@synthesize maximumVisibleRows=_maximumVisibleRows;
@synthesize rowHeight=_rowHeight;

@synthesize delegate=_delegate;
@synthesize dataSource=_dataSource;

@dynamic tableViewDelegate;
@dynamic tableViewDataSource;
@dynamic alertViewDelegate;

@synthesize shadow = _shadow;
@synthesize presented = _presented;

- (id)initWithTitle:(NSString *)title cancelButtonTitle:(NSString *)cancelTitle messageFormat:(NSString *)format args:(va_list)args {
    if ((self = [super init])) {
        NSString *message = format ? [[[NSString alloc] initWithFormat:format arguments:args] autorelease] : nil;

        _alertView = [[UIAlertView alloc] initWithTitle:title message:message delegate:self cancelButtonTitle:cancelTitle otherButtonTitles:nil];

        _maximumVisibleRows = 4;
        _rowHeight = 40.;

        _tableView = [[SBTableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];

        [_tableView setDelegate:self];
        [_tableView setDataSource:self];
        [_tableView setBackgroundColor:[UIColor whiteColor]];
        [_tableView setRowHeight:_rowHeight];
        [_tableView setSeparatorColor:[UIColor lightGrayColor]];
        [_tableView.layer setCornerRadius:kTableCornerRadius];

        [_alertView addSubview:_tableView];

        _shadow = [[SBTableViewTopShadowView alloc] initWithFrame:CGRectZero];
        [_shadow setBackgroundColor:[UIColor clearColor]];
        [_shadow setHidden:YES];
        [_shadow.layer setCornerRadius:kTableCornerRadius];
        [_shadow.layer setMasksToBounds:YES];

        [_alertView addSubview:_shadow];
        [_alertView bringSubviewToFront:_shadow];

        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(layoutAfterSomeTime) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
    }

    return self;
}

- (id)initWithTitle:(NSString *)title cancelButtonTitle:(NSString *)cancelTitle messageFormat:(NSString *)message, ... {
    va_list list;
    va_start(list, message);
    self = [self initWithTitle:title cancelButtonTitle:cancelTitle messageFormat:message args:list];
    va_end(list);
    return self;
}

+ (id)alertWithTitle:(NSString *)title cancelButtonTitle:(NSString *)cancelTitle messageFormat:(NSString *)message, ... {
    return [[[SBTableAlert alloc] initWithTitle:title cancelButtonTitle:cancelTitle messageFormat:message] autorelease];
}

- (void)dealloc {
    [self setTableView:nil];
    [self setView:nil];

    [self setShadow:nil];

    [[NSNotificationCenter defaultCenter] removeObserver:self];

    [super dealloc];
}

#pragma mark -

- (void)show {
    [_tableView reloadData];
    [_alertView show];
}

#pragma mark - Properties

- (void)setStyle:(SBTableAlertStyle)style {
    if (style == SBTableAlertStyleApple) {
        [_tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
        [(SBTableView *)_tableView setAlertStyle:SBTableAlertStyleApple];
        [_shadow setHidden:NO];
    } else if (style == SBTableAlertStylePlain) {
        [_tableView setSeparatorStyle:UITableViewCellSeparatorStyleSingleLine];
        [(SBTableView *)_tableView setAlertStyle:SBTableAlertStylePlain];
        [_shadow setHidden:YES];
    }
    _style = style;
}

- (id<UITableViewDelegate>)tableViewDelegate {
    return _tableView.delegate;
}

- (void)setTableViewDelegate:(id<UITableViewDelegate>)tableViewDelegate {
    [_tableView setDelegate:tableViewDelegate];
}

- (id<UITableViewDataSource>)tableViewDataSource {
    return _tableView.dataSource;
}

- (void)setTableViewDataSource:(id<UITableViewDataSource>)tableViewDataSource {
    [_tableView setDataSource:tableViewDataSource];
}

- (id<UIAlertViewDelegate>)alertViewDelegate {
    return _alertView.delegate;
}

- (void)setAlertViewDelegate:(id<UIAlertViewDelegate>)alertViewDelegate {
    [_alertView setDelegate:alertViewDelegate];
}


#pragma mark - Private

- (void)increaseHeightBy:(CGFloat)delta {
    CGPoint c = _alertView.center;
    CGRect r = _alertView.frame;
    r.size.height += delta;
    _alertView.frame = r;
    _alertView.center = c;
    _alertView.frame = CGRectIntegral(_alertView.frame);

    for(UIView *subview in [_alertView subviews]) {
        if([subview isKindOfClass:[UIControl class]]) {
            CGRect frame = subview.frame;
            frame.origin.y += delta;
            subview.frame = frame;
        }
    }
}


- (void)layout {
    CGFloat height = 0.;
    NSInteger rows = 0;
    for (NSInteger section = 0; section < [_tableView numberOfSections]; section++) {
        for (NSInteger row = 0; row < [_tableView numberOfRowsInSection:section]; row++) {
            height += [_tableView.delegate tableView:_tableView heightForRowAtIndexPath:[NSIndexPath indexPathForRow:row inSection:section]];
            rows ++;
        }
    }

    CGRect screenRect = [[UIScreen mainScreen] bounds];
    CGFloat avgRowHeight = height / rows;
    CGFloat resultHeigh;

    if(height > screenRect.size.height) {
        if(UIDeviceOrientationIsPortrait([UIDevice currentDevice].orientation))
            resultHeigh = screenRect.size.height - _alertView.frame.size.height - 65.;
        else
            resultHeigh = screenRect.size.width - _alertView.frame.size.height - 65.;
    }
    else if (_maximumVisibleRows == -1 || rows <= _maximumVisibleRows)
        resultHeigh = _tableView.contentSize.height;
    else
        resultHeigh = (avgRowHeight * _maximumVisibleRows);

    [self increaseHeightBy:resultHeigh];


    [_tableView setFrame:CGRectMake(12,
                                                                    _alertView.frame.size.height - resultHeigh - 65,
                                                                    _alertView.frame.size.width - 24,
                                                                    resultHeigh)];

    [_shadow setFrame:CGRectMake(_tableView.frame.origin.x,
                                                             _tableView.frame.origin.y,
                                                             _tableView.frame.size.width,
                                                             8)];
}

- (void)layoutAfterSomeTime{
    [NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(layout) userInfo:nil repeats:NO];
}

#pragma mark -
#pragma mark UITableViewDelegate

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    if ([_delegate respondsToSelector:@selector(tableAlert:heightForRowAtIndexPath:)])
        return [_delegate tableAlert:self heightForRowAtIndexPath:indexPath];

    return _rowHeight;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    if (_type == SBTableAlertTypeSingleSelect)
        [_alertView dismissWithClickedButtonIndex:-1 animated:YES];

    if ([_delegate respondsToSelector:@selector(tableAlert:didSelectRowAtIndexPath:)])
        [_delegate tableAlert:self didSelectRowAtIndexPath:indexPath];
}

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    if ([_dataSource respondsToSelector:@selector(tableAlert:titleForHeaderInSection:)]) {
        NSString *title = [_dataSource tableAlert:self titleForHeaderInSection:section];
        if (!title)
            return nil;

        return [[[SBTableViewSectionHeaderView alloc] initWithTitle:title] autorelease];
    }

    return nil;
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    if ([self tableView:tableView viewForHeaderInSection:section])
        return 25.;
    return 0.;
}

#pragma mark -
#pragma mark UITableViewDataSource

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {    
    return [_dataSource tableAlert:self cellForRowAtIndexPath:indexPath];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [_dataSource tableAlert:self numberOfRowsInSection:section];
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    if ([_dataSource respondsToSelector:@selector(numberOfSectionsInTableAlert:)])
        return [_dataSource numberOfSectionsInTableAlert:self];

    return 1;
}

#pragma mark -
#pragma mark UIAlertViewDelegate

- (void)alertViewCancel:(UIAlertView *)alertView {
    if ([_delegate respondsToSelector:@selector(tableAlertCancel:)])
        [_delegate tableAlertCancel:self];
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    if ([_delegate respondsToSelector:@selector(tableAlert:clickedButtonAtIndex:)])
        [_delegate tableAlert:self clickedButtonAtIndex:buttonIndex];
}

- (void)willPresentAlertView:(UIAlertView *)alertView {
    if (!_presented)
        [self layout];
    _presented = YES;
    if ([_delegate respondsToSelector:@selector(willPresentTableAlert:)])
        [_delegate willPresentTableAlert:self];
}
- (void)didPresentAlertView:(UIAlertView *)alertView {
    if ([_delegate respondsToSelector:@selector(didPresentTableAlert:)])
        [_delegate didPresentTableAlert:self];
}

- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex {
    if ([_delegate respondsToSelector:@selector(tableAlert:willDismissWithButtonIndex:)])
        [_delegate tableAlert:self willDismissWithButtonIndex:buttonIndex];
}
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
    _presented = NO;
    if ([_delegate respondsToSelector:@selector(tableAlert:didDismissWithButtonIndex:)])
        [_delegate tableAlert:self didDismissWithButtonIndex:buttonIndex];
}

@end

我把-fno-objc-arc标志放在上面,但是当我试着打开它时它给了我一个

*** -[SBTableAlert tableView:cellForRowAtIndexPath:]: message sent to deallocated instance 0x816b8c0

错误

我打开它:

SBTableAlert   *alert;
    alert   = [[SBTableAlert alloc] initWithTitle:NSLocalizedString(@"servers", nil) cancelButtonTitle:NSLocalizedString(@"cancel", nil) messageFormat:nil];
    [alert setDelegate:self];
    [alert setDataSource:self];
    [alert.view setTag:1];

    [alert show];

任何人都知道如何处理它?<​​/ p>

1 个答案:

答案 0 :(得分:2)

神圣的判决,蝙蝠侠!尝试将这些嵌套方法调用分解为多行,因为它会使代码更具可读性。

鉴于最终表达式是生成错误消息的表达式,它看起来像一个数组中的对象 - 叶节点/数据对象 - 被过度释放。

因此,错误在于创建数组的任何东西。

BTW:方法应始终以小写字母开头,绝不应以get为前缀。因此,该方法将是tableFromLevel:section:parent:array:或类似的东西。按照惯例,get*作为前缀保留给通过引用返回东西的方法。访问者也不以get为前缀。

此外,在注释中指出,无需创建空数组,将其分配给self.allData,然后立即覆盖它。由于autorelease而不是泄漏,但没有必要这样做。


首先,构建并分析您的代码。修复它抱怨的任何内容。

接下来,如果仍然发生崩溃,请使用Allocations仪器并启用Zombie detection。它应该允许您查看发送到崩溃对象的保留/释放。