__block:将块内的变量分配给外部变量不起作用

时间:2013-09-20 18:32:38

标签: ios automatic-ref-counting objective-c-blocks weak-references

根据here找到的建议,我编写了以下代码:

__weak __block NSMutableArray *articlesArray = nil; // I'm using ARC
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:@"http://www.xente.mundo-r.com/turkish/json/lakari.json"]];

    NSMutableURLRequest *request = [httpClient requestWithMethod:@"GET"
                                                            path:@"http://www.xente.mundo-r.com/turkish/json/lakari.json"
                                                      parameters:nil];

    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
    [httpClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];
    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
        // Print the response body in text

        NSData *data = [NSData dataWithData:responseObject];
        NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
        NSMutableArray *articles = [[NSMutableArray alloc]initWithCapacity:jsonArray.count];

        for (NSDictionary *articleDictionary in jsonArray) {
            LOArticulo *articulo = [[LOArticulo alloc]init];
            articulo.ID = articleDictionary[@"id"];
            articulo.marca = articleDictionary[@"marca"];
            articulo.modelo = articleDictionary[@"modelo"];
            articulo.price = articleDictionary[@"precio"];
            articulo.categoria = articleDictionary[@"categoria"];
            articulo.photoURL = articleDictionary[@"photoUrl"];
            [articles addObject:articulo];
        }

        articlesArray = articles; 

    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Error: %@", error);
    }];
    [operation start];

    return articlesArray;

问题是该方法返回null。

你能帮帮我吗? 谢谢。

新代码,至少app不会崩溃。

#import <Foundation/Foundation.h>

@interface LOArticulos : NSObject

@property (strong,nonatomic)NSArray *todosLosArticulos;

+ (LOArticulos *)sharedInstance;

-(void)loadArticlesFromJSON;

@end

Imlementation:

#import "LOArticulos.h"
#import "LOArticulo.h"
#import "AFNetworking.h"

@interface LOArticulos (){
    NSArray *articlesArray;
}
@property (nonatomic,strong) NSArray *articlesArray;

@end

@implementation LOArticulos
@synthesize articlesArray;

+(LOArticulos *)sharedInstance{
    static LOArticulos *_sharedArticles;

    static dispatch_once_t once;
    dispatch_once(&once, ^{
        _sharedArticles = [[LOArticulos alloc]init];
    });
    return _sharedArticles;
}
-(id)init{


    if (self = [super init]) {
        [self loadArticlesFromJSON];
        self.todosLosArticulos = articlesArray;

    }
    return self;
}

- (void)getJson:(id)jsonObject{
    self.articlesArray = [NSArray new];

    NSData *data = [NSData dataWithData:jsonObject];
    NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
    NSMutableArray *articles = [[NSMutableArray alloc]initWithCapacity:jsonArray.count];
    for (NSDictionary *articleDictionary in jsonArray) {
        LOArticulo *articulo = [[LOArticulo alloc]init];
        articulo.ID = articleDictionary[@"id"];
        articulo.marca = articleDictionary[@"marca"];
        articulo.modelo = articleDictionary[@"modelo"];
        articulo.price = articleDictionary[@"precio"];
        articulo.categoria = articleDictionary[@"categoria"];
        articulo.photoURL = articleDictionary[@"photoUrl"];
        [articles addObject:articulo];
    }
    self.articlesArray = [articles copy];
}

-(void)loadArticlesFromJSON{

    AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:@"http://www.xente.mundo-r.com/turkish/json/lakari.json"]];

    NSMutableURLRequest *request = [httpClient requestWithMethod:@"GET"
                                                            path:@"http://www.xente.mundo-r.com/turkish/json/lakari.json"
                                                      parameters:nil];

    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
    [httpClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];
    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {

        [self getJson:responseObject];

    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Error: %@", error);
    }];
    [operation start];
}

@end

2 个答案:

答案 0 :(得分:4)

您的代码实际上存在两个问题,导致articlesArray为nil。

  1. 当您返回articlesArray时,异步操作很可能无法完成。这已经说明了。
  2. 您已将articlesArray声明为弱指针。从概念上讲,这意味着“只有在某人其他强烈引用它时才会将其保留在记忆中”。完成块结束后,文章将超出范围,因此articlesArray将设置为nil。

答案 1 :(得分:1)

为了扩展H2C03所说的内容,我认为正在发生的是你的方法在异步操作完成之前返回,因此articlesArray的值仍为零。