Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7903441
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 3, 20262026-06-03T09:45:20+00:00 2026-06-03T09:45:20+00:00

When writing a method that accepts a block as an argument, do I need

  • 0

When writing a method that accepts a block as an argument, do I need to do anything special such as copying the block to the heap before executing it? For example, if I had the following method:

- (void)testWithBlock:(void (^)(NSString *))block {
    NSString *testString = @"Test";
    block(testString);
}

Should I do anything with block before calling it, or when entering the method? Or is the above the correct way of using the passed-in block? Also, is the following way of calling the method correct, or should I do something with the block before passing it?

[object testWithBlock:^(NSString *test){
    NSLog(@"[%@]", test);
}];

Where do I need to copy the block? And how would this have been different if I wasn’t using ARC?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-03T09:45:22+00:00Added an answer on June 3, 2026 at 9:45 am

    When you receive a block as a method parameter, that block could be the original that had been created on the stack or it could be copy (a block on the heap). As far as I’m aware, there’s no way tell. So the general rule of thumb is if you’re going to execute the block within the method that’s receiving it, you don’t need to copy it. If you intend to pass that block to another method (which may or may not execute it immediately) then you also don’t need to copy it (the receiving method should copy it if it intends to keep it around). However, if you intend to store the block in any way for some place for later execution, you need to copy it. The primary example many people use is some sort of completion block held as an instance variable:

    typedef void (^IDBlock) (id);
    @implementation MyClass{
        IDBlock _completionBlock;
    }
    

    However, you also need to copy it if you’re going to add it to any kind of collection class, like an NSArray or NSDictionary. Otherwise, you’ll get errors (most likely EXC_BAD_ACCESS) or possibly data corruption when you try to execute the block later.

    When you execute a block, it’s important to test first if the block is nil. Objective-c will allow you to pass nil to a block method parameter. If that block is nil, you’ll get EXC_BAD_ACCESS when you try to execute it. Luckily this is easy to do. In your example, you’d write:

    - (void)testWithBlock:(void (^)(NSString *))block {
        NSString *testString = @"Test";
        if (block) block(testString);
    }
    

    There are performance considerations in copying blocks. Compared to creating a block on the stack, copying a block to the heap is not trivial. It’s not a major deal in general, but if you’re using a block iteratively or using a bunch of blocks iteratively and copying them on each execution, it’ll create a performance hit. So if your method - (void)testWithBlock:(void (^)(NSString *))block; were in some kind of loop, copying that block might hurt your performance if you don’t need to copy it.

    Another place you need to copy a block is if you intend on calling that block in itself (block recursion). This isn’t all that common, but you must copy the block if you intend to do this. See my question/answer on SO here: Recursive Blocks In Objective-C.

    Finally, if you’re going to store a block you need to be really careful about creating retain cycles. Blocks will retain any object passed into it, and if that object is an instance variable, it will retain the instance variable’s class (self). I personally love blocks and use them all the time. But there’s a reason Apple doesn’t use/store blocks for their UIKit classes and instead stick with either a target/action or delegate pattern. If you (the class creating the block) are retaining the class that is receiving/copying/storing the block, and in that block you reference either yourself or ANY class instance variable, you’ve created a retain cycle (classA -> classB -> block -> classA). This is remarkably easy to do, and it’s something I’ve done too many times. Moreover, “Leaks” in Instruments doesn’t catch it. The method to get around this is easy: simply create a temporary __weak variable (for ARC) or __block variable (non-ARC) and the block won’t retain that variable. So,for example, the following would be a retain cycle if the ‘object’ copies/stores the block:

    [object testWithBlock:^(NSString *test){
        _iVar = test;
        NSLog(@"[%@]", test);
    }];
    

    However, to fix this (using ARC):

    __weak IVarClass *iVar = _iVar;
    [object testWithBlock:^(NSString *test){
        iVar = test;
        NSLog(@"[%@]", test);
    }];
    

    You can also do something like this:

    __weak ClassOfSelf _self = self;
    [object testWithBlock:^(NSString *test){
        _self->_iVar = test;
        NSLog(@"[%@]", test);
    }];
    

    Note that many people don’t like the above because they consider it fragile, but it is a valid way of accessing variables.
    Update – The current compiler now warns if you try to directly access a variable using ‘->’. For this reason (as well as reasons of safety) it’s best to create a property for the variables you want to access. So instead of _self->_iVar = test; you would use: _self.iVar = test;.

    UPDATE (more info)

    Generally, it’s best to consider the method that receives the block as responsible for determining whether the block needs to be copied rather than the caller. This is because the receiving method can be the only one that knows just how long the block needs to be kept alive or if it needs to be copied. You (as the programmer) will obviously know this information when you write the call, but if you mentally consider the caller and receiver at separate objects, the caller gives the receiver the block and is done with it. Therefore, it shouldn’t need to know what is done with the block after it’s gone. On the flip side, it’s quite possible that the caller may have already copied the block (maybe it stored the block and is now handing it off to another method) but the receiver (who also intends on storing the block) should still copy the block (even though the block as already been copied). The receiver can’t know that the block has already been copied, and some blocks it receives may be copied while others may not be. Therefore the receiver should always copy a block it intends on keeping around? Make sense? This essentially is good Object Oriented Design Practices. Basically, whoever has the information is responsible for handling it.

    Blocks are used extensively in Apple’s GCD (Grand Central Dispatch) to easily enable multi-threading. In general, you don’t need to copy a block when you dispatch it on GCD. Oddly, this is slightly counter-intuitive (if you think about it) because if you dispatch a block asynchronously, often the method the block was created in will return before the block has executed, which generally would mean the block would expire since it is a stack object. I don’t think that GCD copies the block to the stack (I read that somewhere but have been unable to find it again), instead I think the life of the thread is extended by being put on another thread.

    Mike Ash has extensive articles on blocks, GCD and ARC which you may find useful:

    • Mike Ash: Practical Blocks
    • Mike Ash: Objective-C Blocks vs C++0x Lambdas: Fight!
    • Mike Ash: Q&A – More info on Blocks
    • Mike Ash: Automatic Reference Counting He talks about blocks & ARC in this article.
    • Mike Ash: GCD Is Not Blocks, Blocks Are Not GCD
    • Apple Docs – Introducing Block & GCD
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I need to call a method that accepts a stream argument. The method loads
I am writing a program in c++ that accepts a filename as an argument
When writing Cocoa and implementing a class method that accepts a delegate and one
I'm writing a method that will resize the columns in a datagridview so that
I am writing a deserialization method that converts xml to a Java object. I
I'm writing a cache-eject method that essentially looks like this: while ( myHashSet.Count >
I'm writing the spec for controller: it 'should call the method that performs the
I'm writing tetris right now, I have a method that drops figures one by
I have a method I'm writing that uses reflection to list a class's static
I've got a method in a class that's writing to some string, which calls

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.