Cocoa块作为强指针与拷贝

23 浏览
0 Comments

Cocoa块作为强指针与拷贝

我使用块作为指针工作了多次,对此我有强引用。\n我听说应该使用拷贝,但是使用指针而不是原始对象有什么影响呢?\n编译器从来没有抱怨过,不应该使用\n@property (nonatomic, strong) MyBlock block;\n而应该使用\n@property (nonatomic, copy) MyBlock block;\n据我所知,块只是一个对象,那么为什么还要偏好使用拷贝呢?

0
0 Comments

Cocoa Blocks作为强指针和作为拷贝之间的区别

在Objective-C中,Block是一种特殊的对象,它可以用来存储一段代码并在需要时执行。在使用Block时,我们可以将其作为强指针或拷贝来使用。下面我们来看一下为什么会出现这个问题以及如何解决。

问题的出现原因:

在使用Block时,我们通常会将其存储在一个容器中,比如NSDictionary。然而,由于Block是在栈上分配的,而不是在堆上分配的,当我们将Block存储在栈上时,当作用域结束时,栈帧会被销毁,而Block也会随之销毁。这样就会出现一个悬空指针的问题。

解决方法:

为了解决上述问题,我们可以使用copy关键字将Block从栈上拷贝到堆上。这样就可以确保Block在作用域结束后仍然有效。

具体来说,我们可以使用strong属性来存储Block,并在赋值时使用copy方法:

@property (nonatomic, strong) void (^block)();
self.block = [^{} copy];

这样做可以确保Block在作用域结束后仍然有效,并且不会出现悬空指针的问题。

需要注意的是,上述问题在ARC下已经得到了解决,而在非ARC下仍然存在。在非ARC下,使用copy关键字拷贝Block可以解决该问题。

在使用Cocoa Blocks时,如果将其作为强指针存储在容器中,需要注意作用域结束时的悬空指针问题。为了解决这个问题,可以使用copy关键字将Block从栈上拷贝到堆上。在ARC下,这个问题已经得到了解决,不再需要手动拷贝Block。在非ARC下,使用copy关键字可以解决该问题。

这就是关于Cocoa Blocks作为强指针和拷贝之间区别的原因以及解决方法的总结。希望对大家有所帮助!

0
0 Comments

(Cocoa blocks as strong pointers vs copy)这个问题的出现的原因是因为在MRC和ARC中,对于属性的所有权修饰符的选择会有所不同。在MRC中,属性的所有权修饰符包括assign、retain和copy,而在ARC中引入了strong修饰符。当在MRC中使用strong时,它与retain是同义词。因此,问题就在于retain和copy之间的区别,其中有很大的区别,因为copy的setter会保存给定值的副本。

对于block来说,需要进行拷贝才能在创建它的作用域之外使用(使用block字面量)。由于您的属性将把该值存储为持久存在于函数调用之间的实例变量,并且有可能有人会从创建它的作用域中分配一个空闲的block,所以约定是您必须将其进行拷贝。因此,copy是正确的所有权修饰符。

在ARC中,strong使底层的实例变量__strong,并且copy也使其__strong,并在setter中添加了复制语义。但是,ARC还保证,无论何时将值保存到block指针类型的__strong变量中,都会执行拷贝。您的属性的类型为MyBlock,我假设它是一个block指针类型的typedef。因此,如果所有权修饰符为strong,则在setter中仍然会执行拷贝。所以,在ARC中,对于这个属性使用strong和copy没有区别。

然而,如果这个声明可能同时在MRC和ARC中使用(例如库中的头文件),最好使用copy,这样它就可以在两种情况下正常工作。

0
0 Comments

Cocoa blocks作为强指针与复制之间的问题是出现在block对象的存储上的。block对象可以存储在栈上,这是一种编译器的优化,可以快速地分配和销毁block对象。然而,如果block对象需要超过创建它的函数的生命周期,那么它必须被移到堆上。在block实现最初发布的时候,编译器无法自动处理将block移到堆上的操作,所以程序员必须手动使用函数`block_copy()`来进行复制。

尽管现在不再需要手动复制block对象,但是苹果仍然将使用`copy`作为block属性的属性标识符视为最佳实践。然而,这是不必要的,因为存储block对象在栈上本身就是一种优化,代码不应该感知这种优化。

使用ARC和当前的Clang编译器,可以将block对象视为其他对象,不需要复制它们。只有在MRC中才需要手动管理block对象的复制。

关于这个问题的解决方法是,使用ARC和当前的Clang编译器,可以将block对象视为其他对象,不需要复制它们。这是因为存储block对象在栈上本身就是一种优化,代码不应该感知这种优化。

0