找到你要的答案

Q:Encapsulating data and CPTScatterPlot object with delegates into one class

Q:封装数据和cptscatterplot对象代表为一类

I am trying to find a way to encapsulate the data for a plot and the delegate functions in one class. This will make it much simpler to create multiple plots dynamically based on the number of data sets that I acquire.

To do so, I created a class that includes the x, y data points and CPTScatterPlot object, as well as the standard delegate functions, which are now class methods that access the internal data.

When the object is instantiated, the idea is to pass it the data and the graph object, and the constructor makes "self" the data source.

Here is the code:

// 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

When I run the code, I get an "unrecognized selector sent to instance" error, which seems it indicate it is looking for a method that does not exist within the object.

Is there something that I'm doing incorrectly?

Here is the error message:

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)

我试图找到一种方法来封装一个图中的数据和一个类中的委托函数。这将使它更简单地创建多个图动态的基础上,我获得的数据集的数量。

为此,我创建了一个类,包括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)
answer1: 回答1:

The plot's datasource is a dictionary. Check the rest of your code and make sure you're not reassigning the datasource anywhere.

情节的数据源是一个字典。检查您的代码的其余部分,确保你没有指定数据源的任何地方。

core-plot