-2

我刚开始用ARC编程,当我用demo测试时weakstrong @property我发现了一个奇怪的事情;这是代码:

在 .h 文件中,我创建了一个成员变量ctView并添加@property到管理 getter 和 setter。

    @interface ViewController : UIViewController
    {
      CTView * ctView;
    }
    @property(nonatomic,strong)CTView * ctView;

然后在 .m 文件的viewdidload方法中,我将点地址打印出来。

ctView = [[CTView alloc] initWithFrame:CGRectMake(10,10,300,400)];    
NSLog(@"%p %p ",self.ctView,ctView);

日志:

0x0 0x7156530

谢谢大家,我弄错了,MRC 代码是在 LLVM GCC 4.2 编译器上,而 ARC 代码是 Apple LLVM 4.1,这个问题导致 MRC 应用程序崩溃,:)

4

5 回答 5

2

如果您仔细观察,您会发现编译器发出的警告说:

自动合成属性ctView将使用合成变量_ctView,而不是现有变量ctView

这是不言自明的。

发生这种情况是因为现代版本的编译器会在您声明属性时自动合成变量。事实上,跳过该@synthesized指令将导致编译器以这种形式为您插入它

@synthesize ctView = _ctView;

它会自动创建

  • 实例变量_ctView
  • 吸气剂方法-ctView
  • 设置方法-setCtView:

不再需要声明变量@synthesize属性(除非您支持用 Objective-C 1.x 编写的遗留代码),因此您可以完全跳过变量声明和指令。如果你真的想使用你的变量,你必须显式插入

@synthesize ctView; // in this case '= ctView' is implicit, so you can skip it

在您的实现文件中,但您将没有任何好处,并且您还将打破实例变量的命名约定。

于 2013-08-21T08:43:22.210 回答
1

使用新的 Xcode,您不再需要声明 ivar,它会自动创建一个与属性同名但前缀为_. 因此,您的财产的 ivarctView被称为_ctView.

如果你想使用自己的 ivar,你必须告诉编译器:

@synthesize ctView = ctView;
于 2013-08-21T08:43:53.947 回答
1

如果你没有提供你自己的属性的getter和setter的实现,或者你只是@synthesize它们而不提供变量名,Objective-C将自动通过一个名称等于_+属性名的变量来支持你的属性。因此,在您的情况下,您的ctView属性会自动由名为_ctView. 您自己定义的实例变量是一个不同的变量。

您可以通过 3 种方式修复它:

  1. 仅使用 getter 和 setter 来访问您的属性,因此请使用self.ctView = [[CTView alloc] init...而不是ctView = ...删除您自己定义的变量。
  2. 使用正确的名称访问您的实例变量:_ctView = ....
  3. 通过@synthesize ctView = ctView;在 .m 文件中使用,让编译器知道要使用哪个支持变量。
于 2013-08-21T08:49:15.433 回答
1

Xcode4.4 以后不需要@synthesize有实例变量的属性,可以自动完成。但是自动生成的 ivar 的名字是属性的前缀“_”,所以你ctViewiVar 和self.ctView你手动添加的不一样@sythesize ctView=ctView

于 2013-08-21T08:56:04.897 回答
-1

self.ctView,这是一个名为 的 iVar _ctView,永远不会被分配。只有ctView(注意 != _ctView)被分配了。

这就是为什么您没有得到self.ctViewor的地址的原因_ctView

于 2013-08-21T08:41:54.660 回答