2

I want to get comments for a photo from a web server. Server returns an array that includes comments. Is it possible to attach a block instead of comment array to NSMutableDictionary? I want the block to return the comment and insert it's value to dictionary.

I mean some think like this (but it gives compile errors):

 NSArray* (^commentsBlock)(id responseObject) = ^(id responseObject){
        return responseObject;
 };


[self fetchCommentsForNode:[fileInfo objectForKey:@"nid"]
                                       success: commentsBlock];

            VDPhoto *photo = [VDPhoto photoWithProperties:
                              @{@"imageView": imageview,
                                @"title": [fileInfo objectForKey:@"title"],
                                @"comments" : commentsBlock,
                                }];

            [photos addObject:photo];
zontragon
  • 780
  • 1
  • 9
  • 27
  • Are you basically asking how to put a block in a dictionary? What compile errors does it produce? – Rich Apr 26 '14 at 22:19
  • I want to attach a block to a method as a callback block then I want to add it to a dictionary. When callback block finished it's job I want to see the returned value in the dictionary. – zontragon Apr 26 '14 at 22:22
  • 1
    No I don't think you can do that, you'd have to have the callback set a value on the dictionary, blocks are for executing code, not saving results. – Rich Apr 26 '14 at 22:24
  • You can store blocks into dictionaries. You'd have to store [commentsBlock copy] though. And of course there needs to be code taking the block out of the dictionary and calling it for this to be useful. – gnasher729 Apr 18 '15 at 19:48

2 Answers2

1

Further to the discussion in the comments you probably want to do something like this...

Do something inline in the block for fetchCommentsForNode:success: - update the dictionary:

NSMutableDictionary *properties = [@{@"imageView": imageview,
                                         @"title": [fileInfo objectForKey:@"title"]} mutableCopy];

[self fetchCommentsForNode:[fileInfo objectForKey:@"nid"] success:^(id responseObject){
       properties[@"comments"] = responseObject;
       return responseObject;
}];

VDPhoto *photo = [VDPhoto photoWithProperties:properties];

[photos addObject:photo];

All you have to do is make sure the @property in the VDPhoto you save the properties to in the init method is strong, and not copy and then you can look at the dictionary and you will have your comments set once the success block has been called.

EDIT:

An even better option would be to add a @property (nonatomic, copy) NSArray *comments property to VDPhoto, and then set the result on the fetchCommentsForNode: on that:

VDPhoto *photo = [VDPhoto photoWithProperties:@{@"imageView": imageview,
                                                    @"title": [fileInfo objectForKey:@"title"]}];

[photos addObject:photo];

[self fetchCommentsForNode:[fileInfo objectForKey:@"nid"] success:^(id responseObject){
       photo.comments = responseObject;
       return responseObject;
}];
Rich
  • 8,108
  • 5
  • 46
  • 59
  • `@property (nonatomic, copy) NSArray *comments` Why should I define is as `copy` – zontragon Apr 27 '14 at 09:41
  • @zontragon Ha, I was debating on putting this link into my answer - don't know why I didn't! See [this answer](http://stackoverflow.com/a/8090312/849645) :) – Rich Apr 27 '14 at 09:43
  • Blocks must be copied if you use them after leaving the scope where they are defined. For properties, this is most easily done by declaring the property as "copy". "retain" will often lead to crashes. – gnasher729 Apr 18 '15 at 19:46
0

No, an object can't "become" another object. What you want to do is have the block insert the results array in the dictionary, rather than "become" the results array.

Chuck
  • 234,037
  • 30
  • 302
  • 389