Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
382 views
in Technique[技术] by (71.8m points)

objective c - Storing Blocks in an Array

In Objective-C, I know that blocks are considered objects, so I was wondering if it was possible to store them in an array. This begs the question, are blocks first class objects or are they just treated like objects for the sake of passing them between objects? If they are first class objects, then shouldn't they be storable in arrays?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

EDIT: Without going into too much detail, under ARC, you can now add blocks to collections like any other object (see discussion).

I've left the original answer intact below, since it contains some interesting technical details.


This begs the question, are blocks first class objects or are they just treated like objects for the sake of passing them between objects? If they are first class objects, then shouldn't they be storable in arrays?

Blocks are Objective-C objects that very much behave like every other NSObject, with a couple of key differences:

  • Blocks are always generated by the compiler. They are effectively "alloc/init"ed at runtime as execution passes over the blocks declaration.

  • Blocks are initially created on the stack. Block_copy() or the copy method must be used to move the Block to the heap if the Block is to outlive the current scope (see ARC point below).

  • Blocks don't really have a callable API beyond memory management.

  • To put a Block into a Collection, it must first be copied. Always. Including under ARC. (See comments.) If you don't, there is risk that the stack allocated Block will be autoreleased and your app will later crash.

  • Copying a stack based block will copy all of the captured state, too. If you are making multiple copies of a block, it is more efficient to copy it once, then copy the copy (because copying the copy just bumps the retain count since Blocks are immutable).

  • Under ARC, returning a Block from a method or function "just works"; it'll be automatically copied to the heap and the return will effectively be an autoreleased Block (the compiler may optimize away the autorelease in certain circumstances). Even with ARC, you still need to copy the block before sticking it into a collection.

I've written a couple of blog posts both providing an introduction to blocks and some tips and tricks. You might find them interesting.

And, yes, adding 'em to dictionaries is quite useful. I've written a couple of bits of code where I dropped blocks into dictionaries as command handlers where the key was the command name. Very handy.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...