【发布时间】:2013-12-17 22:06:42
【问题描述】:
我想将动态属性与通用 getter/setter 一起使用,但似乎在某些情况下,ARC 会在不应该释放对象时释放对象。我在这里给出最简单的代码来说明问题。
有效的代码:
我的 Person 类具有一个动态属性“名称”
@interface Person : NSObject
@property (strong, nonatomic) NSString *name;
@end
在实现中,这 2 种方法具有能够设置人名的最少代码。我删除了代码的 getter 部分。
@implementation Person
@dynamic name;
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector
{
// Setter signature for a NSString
return [NSMethodSignature signatureWithObjCTypes:"v@:@"];
}
- (void)forwardInvocation:(NSInvocation *)invocation
{
// Get the NSString to set
NSString *s;
[invocation getArgument:&s atIndex:2];
NSLog(@"The string is: %@",s);
}
@end
在我的 UIViewController 中,我只有一个按钮:
- (IBAction)OnTestClicked:(id)sender
{
Person *p = [[Person alloc] init];
p.name = @"John Doe";
}
并且测试工作正常。我得到了日志
字符串是:John Doe
如果我点击按钮 10 次,我有 10 次正确的日志
问题
如果值 @"John Doe" 不是字符串文字,当我再次单击测试按钮时,应用程序将崩溃。
这是一个使用不使用字符串文字的私有属性“defaultName”的示例。
@interface MyViewController ()
@property (strong, nonatomic) NSString *defaultName;
@end
@implementation MyViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.defaultName = [[NSString alloc] initWithFormat:@"John Doe"];
}
- (IBAction)OnTestClicked:(id)sender
{
Person *p = [[Person alloc] init];
p.name = self.defaultName;
}
如果多次单击测试按钮,我会收到消息
malloc: *** 对象 0xa8257b0 错误:未分配指针被释放
或
malloc: *** 对象 0x8f68430 错误:双重释放
似乎 ARC 正在释放强属性“DefaultName”。但因为我使用的是 ARC,所以无法在 setter 中添加保留......
我该如何解决这个问题?
谢谢
【问题讨论】:
-
简单的解决方案是 使用 synthesize 和
NSObject子类。 (请参阅stackoverflow.com/questions/1160498/…)但是,我认为您可能正在尝试在这里做一些特别的事情?你为什么要在这里使用动态?我见过的dynamic唯一有目的的用例是NSManagedObject子类。 -
如果你这样做会发生什么
p.name = [self.defaultName copy]; -
是的 JRG-Developer,我尝试实现自己的托管对象。而nhgrif,对于副本来说,对于大对象来说并不是最好的解决方案。
标签: ios objective-c dynamic automatic-ref-counting