Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 目标C指针?_Objective C_Oop_Pointers - Fatal编程技术网

Objective c 目标C指针?

Objective c 目标C指针?,objective-c,oop,pointers,Objective C,Oop,Pointers,我是新的编码,并试图与Objective-C的速度。 遇到一些我不懂的代码。我希望有人能 给我澄清一下。在下面的例子中,我不确定*foo2是如何工作的,为什么不发布它 ClassOne *pointer = [[ClassOne alloc]init]; ClassTwo *foo = [[ClassTwo alloc]init], *foo2; foo2 = [foo add: pointer]; [foo release]; foo = foo2 [pointer relea

我是新的编码,并试图与Objective-C的速度。 遇到一些我不懂的代码。我希望有人能 给我澄清一下。在下面的例子中,我不确定*foo2是如何工作的,为什么不发布它

ClassOne *pointer = [[ClassOne alloc]init];

ClassTwo *foo = [[ClassTwo alloc]init], *foo2; 

 foo2 = [foo add: pointer];
 [foo release]; 
 foo = foo2

[pointer release];

[foo release];

因为你还没有发布。您在这里释放引用,而不是释放指针。这不完全是一回事。当您第二次执行[foo release]时,您正在释放在将foo2分配给foo时创建的foo引用

要发布foo2引用,您需要实际调用该引用的release,而不是引用的副本

ClassOne *pointer = [[ClassOne alloc]init];
变量
pointer
是指向class One对象的指针。它为新创建的对象指定了值

ClassTwo *foo = [[ClassTwo alloc]init], *foo2;
*foo
*foo2
是类
ClassTwo
的对象。只有
foo
被分配了一个新创建的对象
foo2
可能指向任何东西,因此在为其赋值之前使用它是不安全的

 foo2 = [foo add: pointer];
foo2
被分配了一个值:我假设class
ClassTwo
add:
消息创建了一个对象(方法的签名应该是
-(ClassTwo*)add:(ClassOne*);

不再需要
foo
指向的对象

 foo = foo2;
[foo release];
变量
foo
被赋予
foo2
的值:两者都指向同一对象

[pointer release];
不再需要
指针指向的对象

 foo = foo2;
[foo release];

不再需要
foo
(以及
foo2
)所指向的对象。

从您的简单示例中,很难说出发生了什么。通常,[class add:]类型方法返回void,因此它们应该发出编译器警告,“void值不会像应该的那样被忽略。”

 foo = foo2;
[foo release];
因此,如果没有更多的信息,就有点难搞清楚

需要记住的几件事:

  • 您可以在objc中将命令发送到“nil”。因此,如果[foo add:pointer]返回nil,那么您可以整天对其调用“release”,而不会产生任何影响

  • 重新计数是你的朋友。您可以在任何NSObject上调用它,以查看有多少对象固定在它上面。这也可能有助于您追踪问题

  • 最后,垃圾收集是否已启动


    • 这取决于什么
      [foo add:pointer]可以。它看起来像是返回了
      foo
      副本并保留了它。这显然是一个糟糕的设计,因为如果返回的对象是副本/引用,那么从方法上看应该很明显。名为
      add:
      的方法不应返回副本

      逐步:

      // this somehow creates a retained copy of foo.
      foo2 = [foo add:pointer];
      
       // foo is released and gets destroyed.
      [foo release];
      
      // makes foo point to the same object as foo2
      // (`foo` has no connection to the former object anymore)
      foo = foo2;
      
      // foo (and foo2 as they point to the same object) are released
      [foo release];
      

      你真正想关注的是指针是如何工作的。我想你还没有理解指针和对象之间的区别


      .

      对于Objective-C Cocoa,我们正在使用半自动引用计数内存管理。为对象分配内存、保留对象或对对象调用
      copy
      方法时,保留计数(引用计数)递增1。在对象上调用
      release
      时,它会将保留计数减一。在对象上调用
      autorelease
      时,将在将来的某个时间点对该对象调用
      release
      (在主运行循环期间,当您自己的代码都没有执行时,因此当您尝试使用它时,它不会从您下方拉出引用)。当保留计数达到0时,可以取消分配对象

      通常,如果您对某个对象调用
      retain
      ,则表示您对该对象感兴趣,并负责在您对该对象不再感兴趣的某个时间点调用
      release
      autorelease
      。同样,如果在对象上调用
      alloc
      copy
      方法,则表示您对该对象感兴趣,并且必须将其与
      release
      autorelease
      匹配

      此链接几乎涵盖了苹果用于(以及您应该使用)内存管理的指导原则:

      让我们逐行检查代码:

      指针
      指向一个新分配的ClassOne对象,保留计数为1,因为我们对它调用了alloc。我们有责任在将来的某个时候调用
      指针上的
      释放
      自动释放

      foo
      指向一个新分配的ClassTwo对象,retain计数为1,因为我们对它调用了alloc。我们有责任在将来的某个时候在
      foo
      上调用
      release
      autorelease

      foo2
      目前没有指向任何特定的内容。使用起来不安全

      指针
      已添加到
      foo
      (不管这意味着什么,我们不知道具体实现)
      foo
      可能调用
      pointer
      上的
      retain
      来表示它对它感兴趣,并将它添加为字段,或者它可能已将
      pointer
      添加到集合中(在这种情况下,集合有责任在添加对象时调用
      retain
      ,在移除对象时调用
      release
      )。在任何情况下,它都不会影响我们的代码块,因此我们不关心引擎盖下发生了什么

      此方法返回的引用可能是
      指针
      本身,也可能是
      指针
      的自动删除副本;我们无法访问API或实现来告诉我们是哪个

      在任何一种情况下,我们都不负责对此对象调用
      release
      。如果该方法的名称中包含
      copy
      ,或者如果我们对返回的引用调用了
      retain
      (例如
      foo2=[[foo-add:pointer]retain];
      ),则保留计数将增加1,我们有责任调用
      release
      autorelea
      
      [foo release];
      
       foo = foo2;
      
      [pointer release];
      
      [foo release];