Ios 修改Objective-C块中的全局变量

Ios 修改Objective-C块中的全局变量,ios,objective-c,Ios,Objective C,所以我有一个实例函数,它接受一个NSInteger作为参数;在函数中,我有一个块。我需要修改传递到函数中的NSInteger。但它不是\u块类型。我该怎么做呢? 原来的函数太复杂了,所以我将在这里放一个简化的版本 //@interface @property(nonatomic) NSInteger input; ... //@implementation [self doThis:self.input]; -(void)doThis:(NSInteger)integer{ [AP

所以我有一个实例函数,它接受一个
NSInteger
作为参数;在函数中,我有一个块。我需要修改传递到函数中的
NSInteger
。但它不是
\u块
类型。我该怎么做呢? 原来的函数太复杂了,所以我将在这里放一个简化的版本

//@interface
@property(nonatomic) NSInteger input; 
...

//@implementation
[self doThis:self.input];

-(void)doThis:(NSInteger)integer{
    [API doSomethingWithThisInteger:integer success:^(NSMutableDictionary *data){
        ...
    } failure:^(NSString *error){
        integer--;
    }
}
我知道我应该传入一个
\uu块
类型变量,但是如果我在函数中初始化了一个新的变量(即
\uu块NSInteger temp=integer
),并将
temp--
而不是
integer--
放在
失败
块中,然后,
self.input
将保持不变,因为初始化语句复制
input
的值,而不是引用它。我在这里该怎么办?有没有办法使新变量成为我传递给函数的变量的引用?谢谢


编辑:问题的解决方案- 使用全局变量而不是属性-

@implementation
NSInteger input;
....
[self doThis:&input]; //sends in the address of the input
....
- (void)doThis:(NSInteger *)integer{ //takes the pointer of the input instead of its actual value so it gets referenced rather than getting copied
    [API doSomethingWithThisInteger:integer success:^(NSMutableDictionary *data){
    ...
} failure:^(NSString *error){
    *integer = *integer - 1; //dereference the pointer to get the value.
}

您必须给一个块一些要修改的变量引用。通过调用
doThis:
您可以通过值传递一个整数(而不是通过引用),因此故障块实际上只获得
整数
值的一个副本,所以原始变量没有机会被修改

这同样适用于
\u块NSInteger temp=integer
-temp获取
整数的副本。块可以修改
temp
,但它只是
integer
的一个副本-因此没有机会更改原始值

要更改该值,请使用:

-(void)doThis
{
    [API doSomethingWithSuccess:^(NSMutableDictionary *data)
    {
        ...
    } 
    failure:^(NSString *error)
    {
        self.input--;
    }
}
通过这种方式,您可以通过
self
获得对输入的引用。然而,在ARC环境中它被认为是不好的,因为
self
被块隐式捕获,这可能导致保留周期。因此,最好的方法是创建对self的弱引用,并让它被块捕获:

-(void)doThis
{
    __weak typeof(self) weakSelf = self;
    [API doSomethingWithSuccess:^(NSMutableDictionary *data)
    {
        ...
    } 
    failure:^(NSString *error)
    {
        weakSelf.input--;
    }
}

另外,你的问题实际上揭示了,你不知道它是如何工作的——指针、按值/按引用传递参数、ObjC块等等。你应该获得更多关于编程语言的理论知识,以避免将来出现此类问题。

Objective-C和C一样,都是按值传递的。它通过将对象放在堆上并通过指针引用它们,将对象焊接到C的顶部。所以你传递的不是对象本身,而是对象的地址。地址本身是按值传递的。但是如果有人知道地址,他们可以去堆中修改对象

您对
的输入此:
是一个参数,
整数
。因此,当调用该方法时,将发生以下情况:

  • 无论您在何处编写参数,都将对其进行求值,并在必要时隐式转换为“NSInteger”
  • 将向方法提供
    NSInteger
    的副本
  • 收到自己的副本后,
    integer
    现在相当于该方法的一个局部变量
  • 例如,你可以做:

    [object doThis:8];
    
    8
    被复制到
    内有效的局部变量中。此:
    ,因此您可以随意修改
    整数
    ,而不必考虑您传入常数的事实


    如果希望
    完成此操作:
    可以修改整数,则需要提供指向该整数的指针。一旦你知道了,在块中使用指针应该不会有问题。指针本身将被捕获,但是,就像将指针传递到方法中一样,如果修改指针指向的对象,那么这将影响其他所有在那里查看的对象。

    您不能这样做。参数按值传递。方法内部对它的任何更改都不会反映在方法之外的任何地方。@rmaddy但我有另一个方法,它将
    (UIScrollView*)scrollview
    作为参数。我传入了self.scrollview
    并在该方法中添加了类似于
    [scrollview addSubview…]
    的内容,它成功了吗?在UI中的工作方式得到了更新?这完全不同。对传递到方法中的对象指针调用方法是一回事。为按值传递的基元类型返回更新的值是完全不同的。属性与此无关。在本例中,您处理的是原始类型的
    NSInteger
    。您需要一个可以将新值传回调用方的完成块。在Objective-C中,所有参数都是按值传递的,无论其类型如何。当然,对于对象指针,它是通过值传递的指针。我知道使用您的方法是可行的,因为这正是我一开始所做的。但在我的例子中,有多个
    self.input
    (它们的用法类似,例如self.input1、self.input2)。我只是想让这个方法变得动态。这并不是说我不懂指针之类的东西,没必要这么刻薄吧?我知道我在做什么。你在对你的问题的评论中与rmaddy的讨论实际上揭示了同样的事情。如果您有一个
    输入数组
    ,请将适当的索引传递给API调用。如果您有许多属性,例如
    input1
    input2
    input3
    ,那么您使用的是错误的模型。这里有很多解决方案,比如运行时属性集,为每个参数和许多其他参数创建单独的函数调用。当你明白指针是什么时,你会看到所有选项。你是来回答问题还是来侮辱提问的人?如果我做了类似于
    (NSInteger)&this.input的事情,对你有意义吗?提供一个指针地址:$属性的要点是,您不需要对存储进行任何假设;大多数情况下,它们直接由实例变量建模,但不一定如此。它们可以计算,或转换为和fr