2015-10-08 1 views
0

Я пытаюсь найти способ инкапсуляции данных для сюжета и функций делегата в один класс. Это упростит динамическое создание нескольких графиков на основе количества наборов данных, которые я получаю.Инкапсулирующие данные и объект CPTScatterPlot с делегатами в один класс

Для этого я создал класс, который включает в себя точки данных x, y и объект CPTScatterPlot, а также стандартные функции делегата, которые теперь являются методами класса, которые обращаются к внутренним данным.

Когда объект создается, идея состоит в передаче ему данных и объекта графика, а конструктор делает «я» источником данных.

Вот код:

// DataScatterPlot.h 

#import <Foundation/Foundation.h> 
#import "CorePlot-CocoaTouch.h" 

@interface DataScatterPlot : NSObject <CPTScatterPlotDataSource> 

@property (nonatomic, strong) CPTScatterPlot *CPTScatterPlotObj; 
@property (nonatomic, strong) NSMutableArray *x; 
@property (nonatomic, strong) NSMutableArray *y; 

- (id) initWithGraph: (CPTXYGraph*) graph DataX: (NSMutableArray*) x andDataY: (NSMutableArray*) y; 

@end 

// DataScatterPlot.m 

#import "DataScatterPlot.h" 

@implementation DataScatterPlot 

-(id) initWithGraph: (CPTXYGraph *)graph DataX:(NSMutableArray *)dataX andDataY:(NSMutableArray *)dataY { 
    self = [super init]; 
    if (self != nil) { 
     self.CPTScatterPlotObj = [[CPTScatterPlot alloc] init]; 
     self.x = dataX; 
     self.y = dataY; 
     self.CPTScatterPlotObj.dataSource = (id<CPTScatterPlotDataSource>) self; 
     [graph addPlot:self.CPTScatterPlotObj];   
    } 
    return self; 
} 

// Delegate method that returns the number of points on the plot 
-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot 
{ 
    NSLog(@"The count is %lu", (unsigned long)[self.x count]); 
    return [self.x count]; 
} 

// Delegate method that returns a single X or Y value for a given plot. 
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index 
{ 
    // For Sigmoid 
    NSNumber *dataX = [self.x objectAtIndex:index]; 
    NSNumber *dataY = [self.y objectAtIndex:index]; 

    // FieldEnum determines if we return an X or Y value. 
    switch (fieldEnum) { 
     case CPTScatterPlotFieldX: 
     { 
      return dataX; 
     } 
     case CPTScatterPlotFieldY: // Y-Axis 
     { 
      return dataY; 
     } 
     default: 
      return [NSNumber numberWithFloat:0]; 
    } 
} 

@end 

Когда я запускаю код, я получаю «непризнанный селектор отправляется, например» ошибка, которая, кажется, что показывают его ищет метод, который не существует в пределах объект.

Есть ли что-то, что я делаю неправильно?

Вот сообщение об ошибке:

2015-10-09 12:02:09.743 SigmoidWithCustomDataClass[1192:10285] -[__NSDictionaryI numberOfRecordsForPlot:]: unrecognized selector sent to instance 0x7f9a2bda7fb0 
2015-10-09 12:02:10.550 SigmoidWithCustomDataClass[1192:10285] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSDictionaryI numberOfRecordsForPlot:]: unrecognized selector sent to instance 0x7f9a2bda7fb0' 
*** First throw call stack: 
(
    0 CoreFoundation      0x000000010f697c65 __exceptionPreprocess + 165 
    1 libobjc.A.dylib      0x000000010f330bb7 objc_exception_throw + 45 
    2 CoreFoundation      0x000000010f69f0ad -[NSObject(NSObject) doesNotRecognizeSelector:] + 205 
    3 CoreFoundation      0x000000010f5f513c ___forwarding___ + 988 
    4 CoreFoundation      0x000000010f5f4cd8 _CF_forwarding_prep_0 + 120 
    5 SigmoidWithCustomDataClass   0x000000010eaae44b -[CPTPlot reloadData] + 94 
    6 SigmoidWithCustomDataClass   0x000000010eaae289 -[CPTPlot drawInContext:] + 36 
    7 QuartzCore       0x000000010ec1b92b CABackingStoreUpdate_ + 2793 
    8 QuartzCore       0x000000010ed21933 ___ZN2CA5Layer8display_Ev_block_invoke + 59 
    9 QuartzCore       0x000000010ed217be _ZN2CA5Layer8display_Ev + 1478 
    10 QuartzCore       0x000000010ed164d9 _ZN2CA5Layer17display_if_neededEPNS_11TransactionE + 301 
    11 QuartzCore       0x000000010ed16561 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 35 
    12 QuartzCore       0x000000010ec8286e _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 242 
    13 QuartzCore       0x000000010ec83a22 _ZN2CA11Transaction6commitEv + 462 
    14 UIKit        0x000000010fcd09ed -[UIApplication _reportMainSceneUpdateFinished:] + 44 
    15 UIKit        0x000000010fcd16b1 -[UIApplication _runWithMainScene:transitionContext:completion:] + 2648 
    16 UIKit        0x000000010fcd0095 -[UIApplication workspaceDidEndTransaction:] + 179 
    17 FrontBoardServices     0x0000000114bb75e5 __31-[FBSSerialQueue performAsync:]_block_invoke_2 + 21 
    18 CoreFoundation      0x000000010f5cb41c __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12 
    19 CoreFoundation      0x000000010f5c1165 __CFRunLoopDoBlocks + 341 
    20 CoreFoundation      0x000000010f5c0f25 __CFRunLoopRun + 2389 
    21 CoreFoundation      0x000000010f5c0366 CFRunLoopRunSpecific + 470 
    22 UIKit        0x000000010fccfb02 -[UIApplication _run] + 413 
    23 UIKit        0x000000010fcd28c0 UIApplicationMain + 1282 
    24 SigmoidWithCustomDataClass   0x000000010eaad71f main + 111 
    25 libdyld.dylib      0x0000000112474145 start + 1 
    26 ???         0x0000000000000001 0x0 + 1 
) 
libc++abi.dylib: terminating with uncaught exception of type NSException 
(lldb) 
+0

Какой селектор он искал? Какой объект получил? Можете ли вы опубликовать фактическое сообщение об ошибке и/или журнал сбоев? –

+0

Я добавил сообщение об ошибке в исходное сообщение (для ограничений длины). Благодаря! Я попытался запустить, добавив точку останова для всех исключений, но она была вызвана в main() и не предоставила больше деталей. Я не использую ничего, связанное с NSDictionaryI, в моем собственном коде. –

ответ

0

DataSource сюжет является словарь. Проверьте остальную часть кода и убедитесь, что вы не переназначаете источник данных нигде.

+0

Оказывается, эта конструкция работает только тогда, когда экземпляр объекта custom (DataScatterPlot) создается как свойство ViewController. Но в случае, если указанный объект все еще создается в ViewController, в качестве локальной переменной генерируется исключение. Должно ли это что-то делать с «неатомическими» или «сохраняющими» свойствами? Или это по совершенно другой причине? Благодарю. –

+0

Сюжет имеет слабую ссылку на его источник данных. Если вы не будете ссылаться на свой «DataScatterPlot», он будет освобожден и память будет повторно использована для какого-либо другого объекта. В этом случае это был словарь. –

+0

Спасибо Эрик! Я использовал сильное свойство NSMutableArray для массива объектов моего пользовательского класса, чтобы заставить его работать для экземпляра нескольких графиков. Это строка кода => 'self.arrayOfDSPObjs = [[NSMutableArray alloc] initWithObjects: dataScatterPlotObj1, dataScatterPlotObj2, nil];' –

Смежные вопросы