Message sent to freed instance using Pinterest SDK

I use the Pinterest iOS SDK to share an item in my iPad app. The following code fragment will always fail with a message sent to deallocated instance in the comment line:

 NSString *clientId = [NSMutableString stringWithString:@"1431665"]; NSLog(@"clientId: %@", clientId); Pinterest *pinterest = [[Pinterest alloc] initWithClientId:clientId]; NSLog(@"gone: %@", clientId); // <- CRASH! 

I am using NSMutableString stringWithString to simulate conditions in my application. I really do not use this line in my code.

Even if clientId not displayed in the last line, the application crashes when the block exits. I guess this is because ARC is trying to release a link that has already been released.

It seems that the Pinterest SDK should do something elusive and destroy the line I'm going through. Is there any way around this while they fix their code?

EDIT 1

Simplified test case.

EDIT 2

It looks like the Pinterest SDK is using the clientId argument. Based on the clang of the ARC documentation , the way to point this to clang is to point this out with __attribute((ns_consumed)) .

New question : Is it possible to specify this ARC without changing the method signature for adding an attribute?

EDIT 3

So it works, but it is ugly, how is sin? Is there another way?

 NSString *clientId = [NSMutableString stringWithString:@"1431665"]; [clientId performSelector:NSSelectorFromString(@"retain")]; // <- UGLY! NSLog(@"clientId: %@", clientId); Pinterest *pinterest = [[Pinterest alloc] initWithClientId:clientId]; NSLog(@"gone: %@", clientId); 
+4
source share
2 answers

I made a static variable representing the Pinterest class:

 //I put this outside my @implementation code at the top of my m file static Pinterest *_pinterest = nil; // instantiating static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _pinterest = [[Pinterest alloc] initWithClientId:clientId]; }); 

I think Pinterest suggested that everyone would use their class as a static singleton, because that is probably what they are doing internally. In fairness, in most cases I do not intend to use multiple client identifiers with one application. I agree, however, this is a stunning observation on their part. They did not even document this behavior, what were they thinking ?!

+2
source

My current workaround, which seems to be the least hacked in our ideas, is a wrapper class that doesn't use ARC:

 + (void) createPinWithClientId:(NSString *)clientId imageURL:(NSURL *)imageURL sourceURL:(NSURL *)sourceURL description:(NSString *)descriptionText { Pinterest *pinterest = [[Pinterest alloc] initWithClientId:clientId]; [pinterest createPinWithImageURL:imageURL sourceURL:sourceURL description:descriptionText]; } 

The key is to disable ARC for a class that does not allow the time statement to free the clientId .

0
source

Source: https://habr.com/ru/post/1486519/


All Articles