I don't really know when do I need to copy a block.
The documentation says when you expect the block to be used after destruction of the scope within which it was declared.
Do I need to copy it when I'm using them as callback methods for example? By copy I mean creating a copy property for my block and saving the block there or somehow sending a copy message. The scope is probably destroyed when a download or something similar is finished. So do I need to copy the block in that case? Can I create circular references this way?
Right now I have a downloader class (to test blocks only, it's too dangerous for me to use it yet) that uses a completion block and when I copy the block the view controller that created the block and the downloader class is not released.
Can you give me some good examples especially using them for finishing async operations like file downloads?
Thanks.
Most of the time methods that take callbacks will copy the block for you
I can think of two cases when you need to copy a block yourself in Objective-C
when you're returning a block from a function
when you're saving a block to a class variable (this is the case that happens when you're implementing a method that accepts a callback at a later point).
Since these are the times the block will drop out of scope before they're used or dealt with.
Related
I successfully hooked BeginScene/EndScene methods of DirectX9's DeviceEx, in order to override regions on the screen of a graphics application. I did it by overriding the first 'line' of the function pointed by the appropriate vtable entry (42 for EndScene) with an x86 jump command.
The problem is that when I would like to call the original EndScene method, I have to write the original code overriden by the jump. This operation is not thread safe, and the application has two devices used by two threads.
I tried overriding the vtable entry or copying it and override the COM interface pointer to the vtable, neither ways worked. I guess the original function pointer is cached somewhere or was optimized in the compilation.
I thought about copying the whole original method body to another memory block, but two problems I'm afraid of: (1) (the easy one I think) I don't know how to discover the length of the method and (2) I don't know if the function body stores offsets which are relative to the location where the function is in memory.
I'm trying to hook WPF's device, if it can help somehow.
Do anyone know a thread safe way for such hooking?
Answering my own question: It seems that for my purpose (performing another method before or instead of the original one within my own process), 'trampoline' is the answer. Generally it means I need to make another code segment that makes exactly what the overriden assembly commands did.
Because it is not an easy task, using an external library is recommended.
A discussion about this topic:
How to create a trampoline function for hook
Apple doc says "In a manually reference-counted environment, local variables used within the block are retained when the block is copied. Use of instance variables within the block will cause the object itself to be retained. "
I was going to check local variable is retained by block or not using retainCount, but failed.
Can anyone help me?
A block won't retain an object unless the block is copied. Since a block can only capture state within the same scope as that captured state, the implementation assumes no need to actually retain anything unless the block is copied for the purposes of escaping the scope of declaration.
Think of it in terms of "execution pointer" (kinda like when you are stepping through code in the debugger).
When the execution pointer passes over a block's declaration, that block captures a snapshot -- copies -- all variables that are used within the block's scope that are not declared within the block itself. For an object, that means the block makes a copy of the reference to the object, not a copy of the object itself.
A block starts on the stack. When a block is copied the first time, it is copied from the stack to the heap using a compiler generated per-block "copy helper" (a simple block may not have a copy helper and might actually never be on the stack). That copy helper will retain any objects referenced by the block (that are not referenced via an __block variable anyway).
They won't be released until the block is released and deallocated.
retainCount is useless.
trust the documentation for the implementation. if that fails or defies your expectation for some reason, provide a sample program.
there's no need to verify the retain count, because that's how it works.
if you do doubt it and want to sanity check it, Instruments can be configured to record reference count operations of NSObjects. in that case, run as usual (launched from Instruments, of course), locate the instances of interest in the list of allocated objects, then evaluate the backtraces of the ref-count-ops of the objects of interest. you should see it in there.
I was under the impression that blocks were supposed to resemble first-class functions and allow for lambda calc-style constructs. From a previous question however, I was told they are actually just objects.
Then I have 2 questions really:
Besides the feature of having access to their defining scope, which
I guess makes them usable in a way resembling C++ "friendship", why
would one go for a block instead of an object then? Are they more
lightweight? Because if not I might as well keep passing objects as
parameters instead of blocks.
Do blocks have a way of keeping an internal state? for instance,
some variable declared inside the block which will retain its value
across invocations.
Besides the feature of having access to their defining scope, which I guess makes them usable in a way resembling C++ "friendship", why would one go for a block instead of an object then?
Flexibility. Less to implement. A block is able to represent more than a parameter list or specific object type.
Are they more lightweight?
Not necessarily. Just consider them another tool in the toolbox, and use them where appropriate (or required).
Do blocks have a way of keeping an internal state? for instance, some variable declared inside the block which will retain its value across invocations.
Yes, they are able to perform reference counting as well as copy stack objects. That doesn't necessarily make them lighter-weight to use than an object representing the parameters you need.
Related
What's the difference between NSInvocation and block?
blocks were supposed to resemble first-class functions [...] they are actually just objects.
They are in fact first-class functions, implemented for the purposes of ObjC as objects. In plain-C, where they are also available, they have a closely-related but non-object-based implementation. You can think about them in whichever way is most convenient at the moment.
why would one go for a block instead of an object then?
A block is an executable chunk of code which automatically captures variables from its enclosing scope. The state and actions of a custom object have to be more explicitly handled, and are less generic; you can't use any old object as a completion argument, whereas an executable object fits that bill perfectly.
Do blocks have a way of keeping an internal state? for instance, some variable declared inside the block which will retain its value across invocations.
Sure, you can declare a static variable just like you could with a function or method:
void (^albatross)(void);
albatross = ^{
static int notoriety;
NSLog(#"%d", notoriety++);
};
albatross();
albatross();
albatross();
albatross();
when i say block i mean:
^(int a) {return a*a;};
besides, block is only support by iOS4 and above.
What is the difference between these two?
An NSInvocation is a message (using a selector) to an object, with optional parameters, which can be executed later (or now), and outside the current context (mind of course what you copy vs retain or reference if you move it). NSInvocation has the benefit that you can selectively copy/refer to exactly what you need.
The block is a secret local function definition, which is able to capture portions of the current thread's context, or altogether. It's also a little easier to configure than an NSInvocation because it automatically captures, copies, and retains the thread (or scope) local context. Blocks can increase your binary size slightly, similar to functions. If taken out of the local context (e.g. when you copy a block), blocks can require quite a bit more CPU time and memory - when compared to NSInvocation.
NSInvocation is an object that encapsulates a message call: the target object, the selector, the arguments and the return value. A block is an object that encapsulates a section of code and some information about the state of the program leading up to that section: specifically it records the variables on the call stack up to the creation of the block.
Both of these can clearly be used as callbacks: you can use an invocation to send a message to an object, or you can execute a block's code just like a function. What's different about them is the way you'd transport state in each case. With an invocation, you either need the target object or one of the parameters to represent the context in which the message is appearing. With a block, this context is captured automatically from the state when the block was created.
To put it very simply, NSInvocation is less powerful than blocks. It just encapsulates a single method call on a single object, whereas blocks can wrap many lines of arbitrary code. Even your very simple squaring block is impossible to represent using an invocation without support from an existing class that would do the squaring itself.
May be my question is stupid. But i would like to get it cleared. We know that functions are loaded in memory only once and when you create new objects, only instance variables gets created, functions are never created. My question is, say suppose there is server and all clients access a method named createCustomer(). Say suppose all clients do something which fired createCustomer on server. So, if the method is in middle of execution and new client fires it. Will the new request be put on wait? or new request also will start executing the method? How does it all get managed when there is only one copy of function in memory? No book mentions answers to this type of questions. So i am posting here where i am bound to get answers :).
Functions are code which is then executed in a memory context. The code can be run many times in parallel (literally in parallel on a multi-processor machine), but each of those calls will execute in a different memory context (from the point of view of local variables and such). At a low level this works because the functions will reference local variables as offsets into memory on something called a "stack" which is pointed to by a processor register called the "stack pointer" (or in some interpreted languages, an analog of that register at a higher level), and the value of this register will be different for different calls to the function. So the x local variable in one call to function foo is in a different location in memory than the x local variable in another call to foo, regardless of whether those calls happen simultaneously.
Instance variables are different, they're referenced via a reference (pointer) to the memory allocated to the instance of an object. Two running copies of the same function might access the same instance variable at exactly the same time; similarly, two different functions might do so. This is why we get into "threading" or concurrency issues, synchronization, locks, race conditions, etc. But it's also one reason things can be highly efficient.
It's called "multi-threading". If each request has its own thread, and the object contains mutable data, each client will have the opportunity to modify the state of the object as they see fit. If the person who wrote the object isn't mindful of thread safety you could end up with an object that's in an inconsistent state between requests.
This is a basic threading issue, you can look it up at http://en.wikipedia.org/wiki/Thread_(computer_science).
Instead of thinking in terms of code that is executed, try to think of memory context of a thread that is changed. It does not matter where and what the actual code happens to be, and if it is the same code or a duplicate or something else.
Basically, it can happen that the function is called while it was already called earlier. The two calls are independent and may even happen to run in parallel (on a multicore machine). The way to achieve this independence is by using different stacks and virtual address spaces for each thread.
There are ways to synchronize calls, so additional callers have to wait until the first call finishes. This is also explained in the above link.