Cocoa 块作为强指针 vs 复制 [英] Cocoa blocks as strong pointers vs copy

查看:20
本文介绍了Cocoa 块作为强指针 vs 复制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我确实多次使用块和我有强引用的指针

I did work several times with blocks as with pointers to which i had strong reference

我听说您应该使用复制,但是将块用作指针而不是原始对象有什么含义?

I heard that you should use copy, but what is the implication in working with blocks as pointers and not with the raw object?

编译器从来没有抱怨过我不应该使用

I never got a complain from the compiler, that i should not use

@property (nonatomic, strong) MyBlock block;

但应该使用

@property (nonatomic, copy) MyBlock block;

据我所知,块只是一个对象,所以为什么要更喜欢复制?

as far as i know, the block is just an object, so why to preferrer copy anyway?

推荐答案

简短回答

答案是历史性的,您完全正确,在当前的 ARC 代码中不需要使用 copy 并且 strong 属性很好.例如,局部变量和全局变量也是如此.

The answer is it is historical, you are completely correct that in current ARC code there is no need to use copy and a strong property is fine. The same goes for instance, local and global variables.

长答案

与其他对象不同,一个块可能存储在堆栈中,这是一个实现优化,因此应该像其他编译器优化一样,不会直接影响写的代码.这种优化有利于创建块,作为方法/函数参数传递,由该函数使用,然后丢弃的常见情况 - 可以在堆栈上快速分配块,然后在没有堆的情况下处理(动态内存池)参与其中.

Unlike other objects a block may be stored on the stack, this is an implementation optimisation and as such should, like other compiler optimisations, not have direct impact on the written code. This optimisation benefits a common case where a block is created, passed as a method/function argument, used by that function, and then discarded - the block can be quickly allocated on the stack and then disposed of without the heap (dynamic memory pool) being involved.

将此与局部变量进行比较,后者(a)在堆栈上创建,(b)在拥有函数/方法返回时自动销毁,(c)可以通过地址传递给拥有函数调用的方法/函数.局部变量的地址不能被存储和使用在其拥有的函数/方法返回后 - 该变量不再存在.

Compare this to local variables, which (a) created on the stack, (b) are automatically destroyed when the owning function/method returns and (c) can be passed-by-address to methods/functions called by the owning function. The address of a local variable cannot be stored and used after its owning function/method has return - the variable no longer exists.

然而,对象预计会比它们的创建函数/方法(如果需要)更持久,因此与局部变量不同,它们被分配在上,并且不会根据它们的创建函数/方法返回,而是基于它们是否仍然需要 - 而这里的需要"现在由 ARC 自动确定.

However objects are expected to outlast their creating function/method (if required), so unlike local variables they are allocated on the heap and are not automatically destroyed based on their creating function/method returning but rather based on whether they are still needed - and "need" here is determined automatically by ARC these days.

在堆栈上创建一个块可以优化一个常见的情况,但它也会导致一个问题——如果块需要比它的创建者更持久,就像对象经常做的那样,那么它必须在其创建者堆栈被销毁之前移动到堆中.

Creating a block on the stack may optimise a common case but it also causes a problem - if the block needs to outlast its creator, as objects often do, then it must be moved to the heap before its creators stack is destroyed.

当块实现首次发布时,在堆栈上存储块的优化对程序员来说是可见的,因为当时的编译器无法在需要时自动处理将块移动到堆中 - 程序员必须使用一个函数 block_copy() 自己做.

When the block implementation was first released the optimisation of storing blocks on the stack was made visible to programmers as the compiler at that time was unable to automatically handle moving the block to the heap when needed - programmers had to use a function block_copy() to do it themselves.

虽然这种方法在低级 C 世界中可能并不合适(并且块是 C 构造的),但让高级 Objective-C 程序员手动管理编译器优化确实不好.随着 Apple 发布了更新版本的编译器改进.早期程序员被告知他们可以用 [block copy] 替换 block_copy(block),以适应普通的 Objective-C 对象.然后编译器开始根据需要自动从堆栈复制块,但这并不总是官方记录.

While this approach might not be out-of-place in the low-level C world (and blocks are C construct), having high-level Objective-C programmers manually manage a compiler optimisation is really not good. As Apple released newer versions of the compiler improvements where made. Early on it programmers were told they could replace block_copy(block) with [block copy], fitting in with normal Objective-C objects. Then the compiler started to automatically copy blocks off stack as needed, but this was not always officially documented.

暂时不需要手动从堆栈中复制块,尽管 Apple 无法摆脱其起源并将其称为最佳实践"——这当然值得商榷.在 2014 年 9 月的最新版本中,Apple 的 使用 Blocks,他们声明块值属性应该使用 copy,但随后立即变得清晰(添加了强调):

There has been no need to manually copy blocks off the stack for a while, though Apple cannot shrug off its origins and refers to doing so as "best practice" - which is certainly debatable. In the latest version, Sept 2014, of Apple's Working with Blocks, they stated that block-valued properties should use copy, but then immediately come clean (emphasis added):

注意:您应该将复制指定为属性属性,因为需要复制块以跟踪其原始范围之外的捕获状态.在使用自动引用计数时,这不是您需要担心的事情,因为它会自动发生,但最好让 property 属性显示结果行为.

Note: You should specify copy as the property attribute, because a block needs to be copied to keep track of its captured state outside of the original scope. This isn’t something you need to worry about when using Automatic Reference Counting, as it will happen automatically, but it’s best practice for the property attribute to show the resultant behavior.

不需要显示结果行为"——首先将块存储在堆栈上是一种优化,并且应该对代码透明——就像其他编译器优化代码一样应该在没有程序员参与的情况下获得性能优势.

There is no need to "show the resultant behavior" - storing the block on the stack in the first place is an optimisation and should be transparent to the code - just like other compiler optimisations the code should gain the performance benefit without the programmer's involvement.

因此,只要您使用 ARC 和当前的 Clang 编译器,您就可以像对待其他对象一样对待块,并且块是不可变的,这意味着您不需要复制它们.相信 Apple,即使他们似乎怀念我们手工做事的美好时光"并鼓励您在代码中留下历史提醒,copy 是不需要的.

So as long as you use ARC and the current Clang compilers you can treat blocks like other objects, and as blocks are immutable that means you don't need to copy them. Trust Apple, even if they appear to be nostalgic for the "good old days when we did things by hand" and encourage you to leave historical reminders in your code, copy is not needed.

你的直觉是对的.

这篇关于Cocoa 块作为强指针 vs 复制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆