【问题标题】:Objective-C - Change the address of a passed-in object pointerObjective-C - 更改传入对象指针的地址
【发布时间】:2011-08-02 02:44:37
【问题描述】:

假设我有一个类似的方法:

- (void)reassignPassedObject:(void *)block;

它被称为

NSLog(@"self 1: %@", self);
[myController reassignPassedObject:^(){return self;}];
NSLog(@"self 2: %@", self);

我想将 'self' 引用重新分配给另一个对象,如下所示:

- (void)reassignPassedObject:(void *)block {
    id holder = block();

    if ( YES ) {
        id newObject = nil; //or NSString or NSArray
        //do something such that output second log is "self 2: (newObject...)"
    }
}

这可能吗?

这似乎应该是公平的游戏,因为我们只是在谈论重新分配指针。我会担心在特定实现中的释放/保留。这里让我感到困惑的挑战是:

  • 它涉及 id 而不是直接指针
  • 涉及块传递变量
  • 这涉及到必须以某种方式重新分配 block() 内的对象地址,在该地址中我们只能访问本地持有者对象。

想法?

【问题讨论】:

  • 你为什么要做这一切???
  • 除了我们不知道您要做什么或为什么要这样做这一事实之外,您是否有任何理由不只使用双指针作为方法参数,然后以这种方式更改您的对象指针?

标签: objective-c c pointers


【解决方案1】:

首先,不要更改代码中的self,除非在init... 的开头通过self=[super init...]

我不知道你为什么要使用块,或者是什么促使你做这一切,但如果你坚持改变指针指向的内容,最标准的基于 C 的方法是将指针传递给多变的。例如

-(void)changeObjectPointedBy:(id*)p{
        *p=@"foo";
}

那么这个可以作为

NSString*q=@"bar";
[self changeObjectPointedBy:&q];
NSLog(@"%@",q); // prints "foo"

注意代码中额外的&*。在尝试滥用块之前,我建议您学习简单的 C。

如果你坚持使用块,我会这样做:

-(void)passMyObjToBlock:(void(^)(id))block
{
     block(@"foo");
}

可以用作

__block NSString*p=@"bar";
[self passMyObjToBlock:^(id obj){
       p=obj;
}];
NSLog(@"%@",p); //prints "foo"

或者,另一种方法是

-(void)reassignPassedObject:(id*(^)())block{
     id*holder=block();
     *holder=@"foo";
}

然后

id* pointerToSelf=&self;
[foo reassignPassedObject:^(){return pointerToSelf}];
// self is now @"bar"

请注意“指向对象的指针”和“指向指​​向对象的指针”之间的区别。为了更改self 所指向的内容,您需要将指向self 的指针传递给函数。这是 C 语言的一个基本限制,如果不使用一对 &*,就无法做到这一点。

【讨论】:

  • 您的指针技术效果很好,如果我们无法让块技术发挥作用,我可能会将其标记为答案。您的块示例试图使用块来重新分配值,而不是像我的示例那样使用块的结果,所以它没有帮助。我的示例大大简化了正在执行的实际代码,这实际上涉及在不同代码点定义的嵌套块。我还想补充一点,这一切都发生在 init 内部......我认为将 self 设置为 nil 或在类集群中设置 self 的自定义子类是公平的游戏。
  • 如果是这样,您能否编辑您的问题以提供更多背景信息,以便我们以更有效的方式回答您?恐怕你把原来的问题简化得太多了。
  • 这个问题确实提供了所有有说服力的信息。如何重新分配由“持有人”代表的原始“自我”?所有的联系都在那里。
【解决方案2】:

虽然您可以分配 self(通常在 init 方法中这样做)但您正在做的事情似乎非常非常错误。

great post on Cocoa With Love 描述了所有这些在 Objective-C 中是如何工作的,并且可能会对此有所了解。

您是否正在尝试完成某些特定的事情?还是您只是希望更好地理解语言?

【讨论】:

  • 我在 init 中执行此操作;我想基于将 self 传递给另一个具有编译时未知选择器和块的对象进行一些动态重新分配。事实上,我在运行时将类创建为一种使用块 imps 的类集群。我的问题似乎是合法的,尽管我承认非常非常异国情调。问题是我只能访问“self”和“id”,它们都不是标准的指针参数,而是特殊的 obj-c 关键字,在逻辑上更难计算。
  • selfid 几乎都是标准的。 self 只是提供给任何方法的隐藏参数:在内部,self 是第一个参数,_cmd 是第二个参数。所以 self 在方法中的行为就像它是函数的参数一样。 id 只是一个指向不透明类型的指针。
猜你喜欢
  • 2013-07-12
  • 1970-01-01
  • 1970-01-01
  • 2013-09-26
  • 2015-06-17
  • 2011-06-17
  • 2021-09-06
  • 1970-01-01
  • 2016-10-24
相关资源
最近更新 更多