Note that there are some explanatory texts on larger screens.

plurals
  1. POIn trouble with NSMutableArray retention
    primarykey
    data
    text
    <p>I've had this problem for a couple of days now, I've googled a lot but found out nothing useful so I thought to ask here. I've got a retention problem with an NSMutableArray, however I can't understand where the trouble is and how to fix it. I am drawing a a line chart using Quartz 2D, and in order to do so I have subclassed UIView with GraphView. The header looks like this:</p> <pre><code>@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 </code></pre> <p>I use the "data" array to store data points to draw, within the drawLineGraphWithContext: method. The addValue: method, on the other hand, is used in the main controller to fill in the data array. In the viewDidLoad of the controller I do, to fill in the data array:</p> <pre><code>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 &lt; 14; i++) { [graphView addValue:data[i]]; } </code></pre> <p>Everything is good at this point, and in debug I can see the array is populated with all elements. The problem is when the drawLineGraphWithContext: method is invoked; for some reason, the array suddenly gets empty and its retain count is 0. I have tried changing the way I access the object, using dot notation or omitting the self, however the behaviour looks the same. Strangely enough, I have tried identifying zombies (with both GDB and Instruments), however none seems to be found. As a matter of fact, then the main loop within the drawLineGraphWithContext: below is started the data array has zero elements, and nothing is drawn. Below complete files (I am omitting irrelevant parts).</p> <p>I am using Xcode 4.2 with Automatic Reference Counting.</p> <p>Thanks in advance to anyone helping!</p> <p>GraphView.h:</p> <pre><code>@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 </code></pre> <p>GraphView.m:</p> <pre><code>#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 &lt; lines; i++) { CGContextMoveToPoint(context, kOffsetX + i * kStepX, kGraphTop); CGContextAddLineToPoint(context, kOffsetX + i * kStepX, kGraphBottom); } int horizontalLines = (kDefaultGraphWidth-kOffsetY)/kStepY; for(int i = 0; i &lt; 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 </code></pre> <p>GRViewController.m:</p> <pre><code>#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 &lt; 14; i++) { [graphView addValue:data[i]]; } } </code></pre> <p>@end</p> <p>GRViewController.h:</p> <pre><code>#import &lt;UIKit/UIKit.h&gt; #import "GraphView.h" @interface GRViewController : UIViewController @property (retain, nonatomic) IBOutlet UIScrollView *scroller; @property (retain, nonatomic) IBOutlet GraphView *graphView; @end </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload