【发布时间】:2011-11-04 16:33:08
【问题描述】:
我已经有这个问题好几天了,我用谷歌搜索了很多,但没有发现任何有用的东西,所以我想在这里问。 我有一个 NSMutableArray 的保留问题,但是我不明白问题出在哪里以及如何解决它。 我正在使用 Quartz 2D 绘制折线图,为此我将 UIView 子类化为 GraphView。标题如下所示:
@interface GraphView : UIView {
NSMutableArray *data;
}
- (void)drawBar:(CGRect)rect context:(CGContextRef)ctx;
- (void)drawLineGraphWithContext:(CGContextRef)ctx;
- (void)addValue:(float)value;
@property(nonatomic, retain) NSMutableArray *data;
@end
我使用“数据”数组来存储要绘制的数据点,在 drawLineGraphWithContext: 方法中。另一方面,addValue: 方法在主控制器中用于填充数据数组。在我做的控制器的viewDidLoad中,填写数据数组:
graphView = [[GraphView alloc] init];
float data[] = {0.7, 0.4, 0.9, 1.0, 0.2, 0.85, 0.11, 0.75, 0.53, 0.44, 0.88, 0.77, 0.99, 0.55};
for(int i = 0; i < 14; i++)
{
[graphView addValue:data[i]];
}
此时一切都很好,在调试中我可以看到数组中填充了所有元素。问题是在调用 drawLineGraphWithContext: 方法时;出于某种原因,数组突然变空,其保留计数为 0。我尝试更改访问对象的方式,使用点表示法或省略 self,但行为看起来相同。奇怪的是,我尝试过识别僵尸(使用 GDB 和 Instruments),但似乎没有找到。事实上,在drawLineGraphWithContext:下面的主循环开始了数据数组有零个元素,并且没有绘制任何内容。下面是完整的文件(我省略了不相关的部分)。
我正在使用带有自动引用计数的 Xcode 4.2。
提前感谢任何提供帮助的人!
GraphView.h:
@interface GraphView : UIView {
NSMutableArray *data;
}
- (void)drawBar:(CGRect)rect context:(CGContextRef)ctx;
- (void)drawLineGraphWithContext:(CGContextRef)ctx;
- (void)addValue:(float)value;
@property(nonatomic, retain) NSMutableArray *data;
@end
GraphView.m:
#import "GraphView.h"
@implementation GraphView
@synthesize data;
- (id) init
{
self = [super init];
if(self) {
data = [NSMutableArray array];
NSLog(@"%s", __FUNCTION__);
}
return self;
}
- (void)addValue:(float)value
{
NSMutableArray *tempArr = [self data];
NSNumber *val = [NSNumber numberWithFloat:value];
[tempArr addObject:val];
[self setData:tempArr];
}
- (void)drawLineGraphWithContext:(CGContextRef)ctx
{
CGContextSetLineWidth(ctx, 2.0);
CGContextSetStrokeColorWithColor(ctx, [[UIColor colorWithRed:1.0 green:0.5 blue:0 alpha:1] CGColor]);
int maxGraphHeight = kGraphHeight - kOffsetY;
CGContextBeginPath(ctx);
CGContextMoveToPoint(ctx, kOffsetX, kGraphHeight - maxGraphHeight * [[[self data] objectAtIndex:0] floatValue]);
int i = 0;
NSMutableArray *arr = [self data];
for(NSNumber *elem in arr)
{
float val = [elem floatValue];
CGContextAddLineToPoint(ctx, kOffsetX + i * kStepX, kGraphHeight - maxGraphHeight * val);
i++;
}
CGContextDrawPath(ctx, kCGPathStroke);
}
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 0.6);
CGContextSetStrokeColorWithColor(context, [[UIColor lightGrayColor] CGColor]);
CGFloat dash[] = {2.0, 2.0};
CGContextSetLineDash(context, 0.0, dash, 2);
int lines = (kDefaultGraphWidth - kOffsetX)/kStepX;
for(int i = 0; i < lines; i++)
{
CGContextMoveToPoint(context, kOffsetX + i * kStepX, kGraphTop);
CGContextAddLineToPoint(context, kOffsetX + i * kStepX, kGraphBottom);
}
int horizontalLines = (kDefaultGraphWidth-kOffsetY)/kStepY;
for(int i = 0; i < horizontalLines; i++)
{
CGContextMoveToPoint(context, kOffsetX, kGraphBottom - kOffsetY - i * kStepY);
CGContextAddLineToPoint(context, kDefaultGraphWidth, kGraphBottom - kOffsetY -i * kStepY);
}
CGContextStrokePath(context);
CGContextSetLineDash(context, 0, NULL, 0);
[self drawLineGraphWithContext:context];
}
@end
GRViewController.m:
#import "GRViewController.h"
@implementation GRViewController
@synthesize scroller;
@synthesize graphView;
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
scroller.contentSize = CGSizeMake(kDefaultGraphWidth, kGraphHeight);
graphView = [[GraphView alloc] init];
float data[] = {0.7, 0.4, 0.9, 1.0, 0.2, 0.85, 0.11, 0.75, 0.53, 0.44, 0.88, 0.77, 0.99, 0.55};
for(int i = 0; i < 14; i++)
{
[graphView addValue:data[i]];
}
}
@结束
GRViewController.h:
#import <UIKit/UIKit.h>
#import "GraphView.h"
@interface GRViewController : UIViewController
@property (retain, nonatomic) IBOutlet UIScrollView *scroller;
@property (retain, nonatomic) IBOutlet GraphView *graphView;
@end
【问题讨论】:
标签: iphone objective-c nsmutablearray xcode4.2