gabor.orosz
gabor.orosz

Reputation: 443

Trouble with adding item into an NSMutableArray inside a block

UPDATE: I just found a tricky part... if I do something like this, it works:

[_friendsArrayInBlock insertObject:@"Bla" atIndex:itemIndex];

But it doesn't:

[_friendsArrayInBlock insertObject:friend atIndex:itemIndex];

Why I cannot add a custom object, but I can add NSString? What's the problem

ORIGINAL PART: Here you can see the relevant code part:

@implementation ORGFriendsTableViewController
{
    NSMutableArray *_friendsArray;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    _friendsArray = [NSMutableArray array];
    __block NSMutableArray *_friendsArrayInBlock = _friendsArray;

    [FBRequestConnection startForMyFriendsWithCompletionHandler: ^(FBRequestConnection *connection,
                                                                   id result,
                                                                   NSError *error) {
        FBGraphObject *fbGraphObject = (FBGraphObject *)result;

        NSMutableArray *userArray = fbGraphObject[@"data"];
        for (FBGraphObject *user in userArray) {

            ORGFBUser *friend = [[ORGFBUser alloc] initWithId:user[@"id"] name:user[@"name"] andPhotoURL:@"someurl"];

            NSInteger itemIndex = 0;
            [_friendsArrayInBlock insertObject:friend atIndex:itemIndex];
            [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForItem:itemIndex inSection:0]] withRowAnimation:UITableViewRowAnimationRight];
        }
    }];
}

The problem appears with on this line:

[_friendsArrayInBlock insertObject:friend atIndex:itemIndex];

Program recieving signal "EXC_BAD_ACCESS"

I think it's related with block concept, and altering a non thread-safe NSMutableArray from it.

Do you have any idea how to fix this?

Upvotes: 0

Views: 3624

Answers (2)

Liolik
Liolik

Reputation: 801

try this

@implementation ORGFriendsTableViewController
{
    NSMutableArray *_friendsArray;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    _friendsArray = [NSMutableArray array];
    __block NSMutableArray *_friendsArrayInBlock = _friendsArray;

    [FBRequestConnection startForMyFriendsWithCompletionHandler: ^(FBRequestConnection *connection,
                                                                   id result,
                                                                   NSError *error) {
        FBGraphObject *fbGraphObject = (FBGraphObject *)result;

        NSMutableArray *userArray = fbGraphObject[@"data"];
        for (FBGraphObject *user in userArray) {

            ORGFBUser *friend = [[ORGFBUser alloc] initWithId:user[@"id"] name:user[@"name"] andPhotoURL:@"someurl"];

            [_friendsArrayInBlock addObject:friend];
            [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:_friendsArrayInBlock.count-1 inSection:0]] withRowAnimation:UITableViewRowAnimationRight];
        }
    }];
    [self.tableView reloadData];
}

Upvotes: -1

trojanfoe
trojanfoe

Reputation: 122391

Blocks can access instance variables without using __block (see this). Therefore this should work:

- (void)viewDidLoad
{
    [super viewDidLoad];

    _friendsArray = [NSMutableArray array];

    [FBRequestConnection startForMyFriendsWithCompletionHandler: ^(FBRequestConnection *connection,
                                                                   id result,
                                                                   NSError *error) {
        FBGraphObject *fbGraphObject = (FBGraphObject *)result;

        NSMutableArray *userArray = fbGraphObject[@"data"];
        for (FBGraphObject *user in userArray) {

            ORGFBUser *friend = [[ORGFBUser alloc] initWithId:user[@"id"] name:user[@"name"] andPhotoURL:@"someurl"];

            NSInteger itemIndex = 0;
            [_friendsArray insertObject:friend atIndex:itemIndex];
            [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForItem:itemIndex inSection:0]] withRowAnimation:UITableViewRowAnimationRight];
        }
    }];
}

Upvotes: 3

Related Questions