gpt4 book ai didi

iphone - 从 ^block 访问属性会导致愚蠢的行为

转载 作者:搜寻专家 更新时间:2023-10-30 20:06:39 25 4
gpt4 key购买 nike

我在 Objective-C 中使用 ^blocks 遇到了一些问题。我正在尝试从一个 block 中设置一个实例变量 - 我已经阅读了一些关于该主题的 Apple 文档,我觉得我已经尝试了所有方法。

@interface MyClass
{
// I have tried all possible combinations using __weak, __strong and __block.
__weak __block NSMutableArray *filenames;
}

// *.m
static ASIFormDataRequest *g_request = nil;

@implementation MyClass
-(void) funnymethod
{
filenames = [NSMutableArray array];
[filenames addObject:@"This is a string."];
NSLog(@"%@", filenames);

g_request = [InitializerClass initializeRequest];
[g_request setCompletionBlock:^
{
filenames = [NSMutableArray array];
[filenames addObject:@"This is another string."];
NSLog(@"%@", filenames);
}];

[g_object startASynchronous];
}
@end

上面的代码给出了以下输出: (“这是一个字符串。”) (空)

太糟糕了。因此,我尝试了 __weak、__strong 和 __block 的不同组合 - 其他任何组合都会产生以下输出: (“这是一个字符串。”) (“这是另一个字符串。”)但!有一个巨大的但是。完成 block 永远不会退出。顶部栏中指示打开的连接的事件指示器不断旋转,屏幕变得无响应。

如何从 block 中成功设置文件名对象?提前致谢。

最佳答案

限定符的作用:

__block 此限定符允许闭包修改存储在给定变量中的值。

__weak 是对不会阻止对象被取消分配的对象的引用。

__strong 是对对象的引用,确实防止对象被取消分配。

您需要做什么:

__weak 不会执行您想要的操作,因为它不会阻止您的数组在当前作用域结束后被取消分配。由于您正在进行异步调用,因此没有什么可以阻止运行时在执行您的 block 之前回收数组使用的内存。

__strong 将保留当前作用域结束后的对象。这就是您想要的。

__block 将允许您的 block 修改指定的变量,但是在引用实例变量时不需要这样做,因为 self 将自动保留。

In a reference-counted environment, by default when you reference an Objective-C object within a block, it is retained. This is true even if you simply reference an instance variable of the object. Object variables marked with the __block storage type modifier, however, are not retained.

Note: In a garbage-collected environment, if you apply both __weak and __block modifiers to a variable, then the block will not ensure that it is kept alive. If you use a block within the implementation of a method, the rules for memory management of object instance variables are more subtle:

If you access an instance variable by reference, self is retained;

我认为您的问题出在这里(相关部分以粗体显示):

You can specify that an imported variable be mutable—that is, read-write— by applying the __block storage type modifier. __block storage is similar to, but mutually exclusive of, the register, auto, and static storage types for local variables.

__block variables live in storage that is shared between the lexical scope of the variable and all blocks and block copies declared or created within the variable’s lexical scope. Thus, the storage will survive the destruction of the stack frame if any copies of the blocks declared within the frame survive beyond the end of the frame (for example, by being enqueued somewhere for later execution). Multiple blocks in a given lexical scope can simultaneously use a shared variable.

As an optimization, block storage starts out on the stack—just like blocks themselves do. If the block is copied using Block_copy (or in Objective-C when the block is sent a copy), variables are copied to the heap. Thus, the address of a __block variable can change over time.

There are two further restrictions on __block variables: they cannot be variable length arrays, and cannot be structures that contain C99 variable-length arrays.

代替 NSMutableArray,尝试使用普通的 NSArray

+ (id)arrayWithObject:(id)anObject

关于iphone - 从 ^block 访问属性会导致愚蠢的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10075258/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com