动态引用变量/对象/数组等

时间:2013-12-09 10:02:17

标签: ios objective-c

这似乎是一件容易的事,至少在VB.net中是这样。我只需要根据传递给方法的字符串引用数组。当视图控制器加载时,调用方法并传递字符串。将基于此字符串创建URL,并将从中获取JSON。我想要的是方法根据传递的字符串填充适当的数组。

这里我们看到方法“goGetData”在类“getData”中被调用,其中包含三个字符串参数之一“workshop / speaker / exhibitor”:

- (void)viewDidLoad
{


[getData goGetData:@"workshop"];
[getData goGetData:@"speaker"];
[getData goGetData:@"exhibitor"];

getData *getDataInstance = [[getData alloc] init];

NSArray *newTablesArray = getDataInstance.jsonAllTables;
NSLog(@"Json currently = %@", newTablesArray);

[super viewDidLoad];

[[self myTableView]setDelegate:self];
[[self myTableView]setDataSource:self];
arrayTable =[[NSMutableArray alloc]init];
}

例如,如果用“speaker”触发“goGetDate”,我需要获取扬声器数据,然后填充“_jsonSpeaker”数组。到目前为止,我尝试根据方法调用中传递的字符串来引用和填充数组:

#import "getData.h"

@implementation getData



+(void)goGetData:(NSString *)requestedTable
{

getData *getDataInstance = [[getData alloc] init];

[getDataInstance buildArray];
[getDataInstance fetchData:requestedTable];

}

-(void)buildArray{
// I tried putting the arrays in an array but still do no know how to reference them
_jsonAllTables = [[NSMutableArray alloc] initWithObjects:_jsonExhibitor, _jsonSpeaker, _jsonWorkshop, nil];

}

-(void)fetchData:(NSString *)requestedTable{
NSString *varCurrentTable;
varCurrentTable = [NSString stringWithFormat:@"_json%@", requestedTable];
NSString *requestedURL;
requestedURL = [NSString stringWithFormat:@"http://testapi.website.com/api/%@", requestedTable];

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:requestedURL]];
[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
 {
     if (response){
         NSHTTPURLResponse *newResp = (NSHTTPURLResponse*)response;

         if (newResp.statusCode == 200) {

             // STUFF FOR TESTING NSLog(@"Response to request: %@ is: %i GOOD", requestedURL, newResp.statusCode);

             if ([data length] >0 && error == nil)
             {
                 // STUFF FOR TESTING NSUInteger indexOfArray = [_jsonAllTables indexOfObject:varCurrentTable];
                 // STUFF FOR TESTING NSString *objectAtIndexOfArray = [_jsonAllTables objectAtIndex:indexOfArray];

             //    This is the part I think I am stuck on:
             //    "CURRENT TABLE TO BE POPULATED" = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];

             }
             else if ([data length] == 0 && error == nil)
             {
                 NSLog(@"Nothing was downloaded");
             }
             else if (error != nil)
             {
                 NSLog(@"Error: %@", error);
             }

         } else if (newResp.statusCode == 404){
              NSLog(@"Response to request: %@ is: %i BAD - URL incorrect", requestedURL, newResp.statusCode);
         } else {
             // add more returned status error handling here
         }

     }else{
         NSLog(@"No response received");
     }

 }];
}

@end

谢谢,

为了澄清我想要达到的目的而添加:为了节省大量的一遍又一遍地写出同样的东西,可能是Obj-c中的以下内容(请原谅语言的混搭)

NSArray *ListOfTables = [NSArray arrayWithObjects:@"Speaker", @"Exhibitor", @"Workshop", nil];

For i as int = 0 to ListOfTables.count{ 

 [self fetchData:(ListOfTables.objectAtIndex = i) withCompletion:^(NSArray* objects, NSError*error){
    dispatch_async(dispatch_get_main_queue(), ^{
        if (objects) {
            self.(ListOfTables.objectAtIndex = i) = objects;
        }
        else {
            NSLog(@"Error: %error", error);
        }
    });
}];
i++;
Next
};

注意我没有为每个表调用单独的方法,而是每次调用相同的方法但使用不同的表名参数。我似乎无法在Xcode中找到这样的占位符的实例。

1 个答案:

答案 0 :(得分:1)

您可能想要一个异步的方法,并通过完成处理程序返回结果:

typedef void(^completion_t)(NSArray* objects, NSError*error);

-(void)fetchData:(NSString *)tableName 
  withCompletion:(completion_t)completionHandler;

用法:

- (void) foo {

    [self fetchData:tableName1 withCompletion:^(NSArray* objects, NSError*error){
        dispatch_async(dispatch_get_main_queue(), ^{
            if (objects) {
                self.table1 = objects;
            }
            else {
                NSLog(@"Error: %error", error);
            }
        });
    }];

    [self fetchData:tableName2 withCompletion:^(NSArray* objects, NSError*error){
        dispatch_async(dispatch_get_main_queue(), ^{
            if (objects) {
                self.table2 = objects;
            }
            else {
                NSLog(@"Error: %error", error);
            }
        });
    }];

    [self fetchData:tableName3 withCompletion:^(NSArray* objects, NSError*error){
        dispatch_async(dispatch_get_main_queue(), ^{
            if (objects) {
                self.table3 = objects;
            }
            else {
                NSLog(@"Error: %error", error);
            }
        });
    }];
} 

实现:

typedef void(^completion_t)(NSArray* objects, NSError* error);

-(void)fetchData:(NSString *)tableName
  withCompletion:(completion_t)completionHandler
{
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:tableName]];
    // Setup HTTP headers, e.g. "Accept: application/json", etc.
    ...
    [NSURLConnection sendAsynchronousRequest:request
                                       queue:[[NSOperationQueue alloc] init]
                           completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
    {
         NSError* err = error;
         NSArray* objects; // final result array as a representation of JSON Array
         if (response) {
             NSHTTPURLResponse *newResp = (NSHTTPURLResponse*)response;
             if (newResp.statusCode == 200) {
                 if ([data length] >0 && error == nil)
                 {
                     NSError* localError;
                     objects = ... // Use NSJSONSerialization to obtain a representation
                     if (objects) {
                         if (completionHandler) {
                             completionHandler(object, nil);
                         }
                         return;
                     }
                     else {
                         err = localError;
                     }
                 }
                 else {
                     err = ...
                 }
             }
         }
         if (objects == nil) {
             assert(err);
             if (completionHandler) {
                 completionHandler(nil, err);
             }
         }
    }];
}

异步循环

另一个例子,用于加载一堆数据:

首先,实现了一个“异步循环”的方法:

typedef void(^completion_t)(id result, NSError* error);

- (void) fetchObjectsWithTableNames:(NSMutableArray*)tableNames 
         completion:(completion_t)completionHandler;

此方法本身是异步的,因此是完成处理程序。

用法:

- (void) foo 
{
    NSArray* tableNames =  @[@"A", @"B", @"C"]; // possibly 1000

    [self fetchObjectsWithTableNames:[tableNames mutableCopy]:^(id result, NSError*error){
        if (error) {
            NSLog(@"Error: %@", error);
        }
        else {
            // finished fetching a bunch of datas with result:
            NSLog(@"Result: %@", result);
        }
    }];
}

实施

- (void) fetchObjectsWithTableNames:(NSMutableArray*)tableNames 
         completion:(completion_t)completionHandler;
{
    if ([tableNames count] > 0) {
        NSString* name = [tableNames firstObject];
        [tableNames removeObjectAtIndex:0];
        [self fetchData:name withCompletion:^(NSArray* objects, NSError*error){
            if (objects) {
                [self.tables addObject:objects];
                [self fetchObjectsWithTableNames:tableNames completion:completionHandler];
            } 
            else  {
               // handle error
            }
        }];
    }
    else {
        // finished
        if (completionHandler) {
            completionHandler(@"finished", nil);
        }
    }
}