我正在使用Pinterest iOS SDK在我的iPad应用程序中共享一个项目.下面的代码片段将始终崩溃,并在评论的行上发送给已释放的实例的消息:
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 documentation,指示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);
最佳答案 我做的是创建一个代表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.但我同意,这对他们来说是一个令人费解的疏忽.他们甚至没有记录这种行为,他们在想什么?!