错误:可写原子属性无法将合成的 setter/getter 与用户定义的 setter/getter 配对

问题描述 投票:0回答:4

我最近尝试编译一个较旧的 Xcode 项目(以前编译得很好),现在我看到很多这种形式的错误:

error: writable atomic property 'someProperty' cannot pair a synthesized setter/getter with a user defined setter/getter

导致这些错误的代码模式总是如下所示:

// Interface:

@property (retain) NSObject * someProperty;

// Implementation:

@synthesize someProperty; // to provide the getter
- (void)setSomeProperty:(NSObject *)newValue
{
    //..
}

我可以明白为什么会产生错误。我告诉编译器合成我的属性访问器(getter 和 setter),然后立即手动重写 setter。该代码总是有点不对劲。

那么,正确的方法是什么?如果我使用

@dynamic
而不是
@synthesize
,我还必须编写 getter。这是唯一的方法吗?

objective-c xcode properties
4个回答
224
投票

我遇到了同样的问题,经过一番研究后,这是我对这个问题的结论:

编译器会警告您声明为原子的

@property
(即通过省略
nonatomic
关键字),但您提供了如何同步对该属性的访问的不完整实现。

要使该警告消失:

如果您将

@property
声明为原子,则执行以下操作之一:

  • 使用
    @dynamic
    或;
  • 使用
    @synthesize
    并保留合成的 setter 和 getter 或;
  • 提供both setter 和 getter 的手动实现(不使用上述指令之一)。

如果您使用

@property
声明
(nonatomic)
,那么您可以混合 getter 和 setter 的手动和合成实现。

更新:属性自动合成注意事项

从 LLVM 4.0 开始,CLang 为非

@dynamic
声明的属性提供自动合成。默认情况下,即使你省略了
@synthesize
,编译器也会为你提供 getter 和 setter 方法。然而,原子属性的规则仍然是相同的:要么让编译器提供 both getter 和 setter,或者自己实现它们 both


14
投票

您还需要实现 getter。示例:

// Interface:

@property (retain) NSObject * someProperty;

// Implementation:

- (void)setSomeProperty:(NSObject *)newValue
{
    @synchronized (self)
    {
        // ...
    }
}

- (NSObject *)someProperty
{
    NSObject *ret = nil;

    @synchronized (self)
    {
        ret = [[someProperty retain] autorelease];
    }

    return ret;
}

12
投票

这个问题,以及您通过搜索“objective C custom property”获得的其他热门搜索结果,并未使用有关“setter =”或“getter =”的信息进行更新。

因此,提供有关此问题的更多信息:

您可以通过编写以下内容来使用您自己的方法提供 @property 调用

    @property(setter = MySetterMethod:, getter = MyGetterMethod)

注意所提供的 setter 方法的冒号。

参考 Apple 文档

编辑: 我不太确定 Objective-C 属性的新变化(它们现在更加智能)如何改变这个问题的答案。也许应该全部标记为已过时。


0
投票

对于其他不是因为OP描述的原因而收到此错误的人,您可能有与我相同的问题:

您有一个与 -() 方法同名的@property。

类似这样的:

@property UIView *mainView;

-(UIView *)mainView;
© www.soinside.com 2019 - 2024. All rights reserved.