4

我正在使用 Pinterest iOS SDK 在我的 iPad 应用程序中共享项目。以下代码片段总是会崩溃,message sent to deallocated instance并在注释所在的行显示 a:

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

NSMutableString stringWithString用来模拟我的应用程序中的条件。我实际上并没有在我的代码中使用该行。

即使不在clientId最后一行输出,应用程序在离开块时也会崩溃。我认为这是因为 ARC 试图释放已经被释放的引用。

似乎 Pinterest SDK 必须做一些奇怪的事情并破坏我传入的字符串。在他们修复他们的代码时有什么方法可以解决这个问题吗?

编辑 1

简化了测试用例。

编辑 2

看起来 Pinterest SDK 正在使用该clientId参数。根据clang ARC 文档,向 clang 表明这一点的方法是用__attribute((ns_consumed)).

新问题:是否可以在不修改方法签名以添加属性的情况下向 ARC 表明这一点?

编辑 3

所以这行得通,但它像罪恶一样丑陋吗?还有其他方法吗?

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

2 回答 2

2

我所做的是创建一个代表 Pinterest 类的静态变量:

//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];
});

我认为 Pinterest 假设每个人都会将他们的类用作静态单例,因为这可能是他们内部所做的。公平地说,在大多数情况下,我预计不会在单个应用程序中使用多个客户端 ID。不过,我同意,这对他们来说是一个令人震惊的疏忽。他们甚至没有记录这种行为,他们在想什么?!

于 2013-10-15T15:52:27.280 回答
0

我目前的解决方法,这似乎是迄今为止最简单的想法是这个不使用 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];
}

关键是禁用该类的 ARC,这样可以防止运行时释放clientId.

于 2013-06-17T18:25:27.840 回答