need assistance understanding objective-c blocks - ios

This is from apple blocks docs and I am having difficulty understanding this please can any one explain in little easy way
...You can cast a block reference to a pointer of arbitrary type and
vice versa. You cannot, however, dereference a block reference via the
pointer dereference operator (*)—thus a block's size cannot be
computed at compile time.

Put simply, a block is a reference. The code within the block is stored in memory, and can be accessed via a variable. void (^addingBlock)(int); is a block declaration, that can be accessed via the addingBlock variable (as in, it can be called like addingBlock(5);).
Now, this reference can be transformed into a pointer type, that C recognises. Sort of like a function pointer. As the documentation states, the only visual difference is the use of * instead of ^. This means you can cast a block to a function pointer:
void (*funcPointer)(int) = (void(*)(int))addingBlock;
Or even a void pointer (or any type!)
void* voidPtr = (void*)addingBlock;
But what the quote you're providing says, is that with this pointer to a block, you can't 'dereference' it. This means to interpret the pointer address, and get the data behind that address. Being unable to do this means you can't determine its size at compile time.
Why? Because of Obj-C's dynamic'ness; the contents of the block can only be determined at run time, whereas C is fairly static in nature, and determines a lot at compile time.

Related

How to check if a pointer has been already disposed? [duplicate]

In another question, I found out that the Assigned() function is identical to Pointer <> nil. It has always been my understanding that Assigned() was detecting these dangling pointers, but now I've learned it does not. Dangling Pointers are those which may have been created at one point, but have since been free'd and haven't been assigned to nil yet.
If Assigned() can't detect dangling pointers, then what can? I'd like to check my object to make sure it's really a valid created object before I try to work with it. I don't use FreeAndNil as many recommend, because I like to be direct. I just use SomeObject.Free.
Access Violations are my worst enemy - I do all I can to prevent their appearance.
If you have an object variable in scope and it may or may not be a valid reference, FreeAndNil is what you should be using. That or fixing your code so that your object references are more tightly managed so it's never a question.
Access Violations shouldn't be thought of as an enemy. They're bugs: they mean you made a mistake that needs fixed. (Or that there's a bug in some code you're relying on, but I find most often that I'm the one who screwed up, especially when dealing with the RTL, VCL, or Win32 API.)
It is sometimes possible to detect when the address a pointer points to resides in a memory block that is on the heap's list of freed memory blocks. However, this requires comparing the pointer to potentially every block in the heap's free list which could contain thousands of blocks. So, this is potentially a computationally intensive operation and something you would not want to do frequently except perhaps in a severe diagnostic mode.
This technique only works while the memory block that the pointer used to point to continues to sit in the heap free list. As new objects are allocated from the heap, it is likely that the freed memory block will be removed from the heap free list and put back into active play as the home of a new, different object. The original dangling pointer still points to the same address, but the object living at that address has changed. If the newly allocated object is of the same (or compatible) type as the original object now freed, there is practically no way to know that the pointer originated as a reference to the previous object. In fact, in this very special and rare situation, the dangling pointer will actually work perfectly well. The only observable problem might be if someone notices that the data has changed out from under the pointer unexpectedly.
Unless you are allocating and freeing the same object types over and over again in rapid succession, chances are slim that the new object allocated from that freed memory block will be the same type as the original. When the types of the original and the new object are different, you have a chance of figuring out that the content has changed out from under the pointer. However, to do that you need a way to know the type of the original object that the pointer referred to. In many situations in native compiled applications, the type of the pointer variable itself is not retained at runtime. A pointer is a pointer as far as the CPU is concerned - the hardware knows very little of data types. In a severe diagnostic mode it's conceivable that you could build a lookup table to associate every pointer variable with the type allocated and assigned to it, but this is an enormous task.
That's why Assigned() is not an assertion that the pointer is valid. It just tests that the pointer is not nil.
Why did Borland create the Assigned() function to begin with? To further hide pointerisms from novice and occasional programmers. Function calls are easier to read and understand than pointer operations.
The bottom line is that you should not be attempting to detect dangling pointers in code. If you are going to refer to pointers after they have been freed, set the pointer to nil when you free it. But the best approach is not to refer to pointers after they have been freed.
So, how do you avoid referring to pointers after they have been freed? There are a couple of common idioms that get you a long way.
Create objects in a constructor and destroy them in the destructor. Then you simply cannot refer to the pointer before creation or after destruction.
Use a local variable pointer that is created at the beginning of the function and destroyed as the last act of the function.
One thing I would strongly recommend is to avoid writing if Assigned() tests into your code unless it is expected behaviour that the pointer may not be created. Your code will become hard to read and you will also lose track of whether the pointer being nil is to be expected or is a bug.
Of course we all do make mistakes and leave dangling pointers. Using FreeAndNil is one cheap way to ensure that dangling pointer access is detected. A more effective method is to use FastMM in full debug mode. I cannot recommend this highly enough. If you are not using this wonderful tool, you should start doing so ASAP.
If you find yourself struggling with dangling pointers and you find it hard to work out why then you probably need to refactor the code to fit into one of the two idioms above.
You can draw a parallel with array indexing errors. My advice is not to check in code for validity of index. Instead use range checking and let the tools do the work and keep the code clean. The exception to this is where the input comes from outside your program, e.g. user input.
My parting shot: only ever write if Assigned if it is normal behaviour for the pointer to be nil.
Use a memory manager, such as FastMM, that provides debugging support, in particular to fill a block of freed memory with a given byte pattern. You can then dereference the pointer to see if it points at a memory block that starts with the byte pattern, or you can let the code run normallly ad raise an AV if it tries to access a freed memory block through a dangling pointer. The AV's reported memory address will usually be either exactly as, or close to, the byte pattern.
Nothing can find a dangling (once valid but then not) pointer. It's your responsibility to either make sure it's set to nil when you free it's content, or to limit the scope of the pointer variable to only be available within the scope it's valid. (The second is the better solution whenever possible.)
The core point is that the way how objects are implemented in Delphi has some built-in design drawbacks:
there is no distinction between an object and a reference to an object. For "normal" variables, say a scalar (like int) or a record, these two use cases can be well told apart - there's either a type Integer or TSomeRec, or a type like PInteger = ^Integer or PSomeRec = ^TSomeRec, which are different types. This may sound like a neglectable technicality, but it isn't: a SomeRec: TSomeRec denotes "this scope is the original owner of that record and controls its lifecycle", while SomeRec: PSomeRec tells "this scope uses a transient reference to some data, but has no control over the record's lifecycle. So, as dumb it may sound, for objects there's virtually no one who has denotedly control over other objects' lifecycles. The result is - surprise - that the lifecycle state of objects may in certain situations be unclear.
an object reference is just a simple pointer. Basically, that's ok, but the problem is that there's sure a lot of code out there which treats object references as if they were a 32bit or 64bit integer number. So if e.g. Embarcadero wanted to change the implementation of an object reference (and make it not a simple pointer any more), they would break a lot of code.
But if Embarcadero wanted to eliminate dangling object pointers, they would have to redesign Delphi object references:
when an object is freed, all references to it must be freed, too. This is only possible by double-linking both, i.e. the object instance must carry a list with all of the references to it, that is, all memory addresses where such pointers are (on the lowest level). Upon destruction, that list is traversed, and all those pointers are set to nil
a little more comfortable solution were that the "one" holding such a reference can register a callback to get informed when a referenced object is destroyed. In code: when I have a reference FSomeObject: TSomeObject I would want to be able to write in e.g. SetSomeObject: FSomeObject.OnDestruction := Self.HandleDestructionOfSomeObject. But then FSomeObject can't be a pointer; instead, it would have to be at least an (advanced) record type
Of course I can implement all that by myself, but that is tedious, and isn't it something that should be addressed by the language itself? They also managed to implement for x in ...

Without knowing the userdata implementation, can I use its fields from inside C++?

I can obtain a userdata from inside my C++ code. I want to know if I can cast it to something so I can dereference its fields and invoke its methods without going through Lua.
In other words:
Once I obtain an userdata and put it in the Lua stack, how can I get it out and use it as an object of a certain class? I know all fields and methods that I'm interested in (their Lua names), but not necessarily all fields and method the userdata underlying implementation provides.
Is there a way to somehow create an interface that would know the offsets of each member?
I believe the question is, how do I know the offset of each member in the Lua view of the userdata, so I can create a struct to cast the void * returned by lua_touserdata to?
Userdata is just a binary blob. Array of bytes. How those bytes will be interpreted - depends entirely on interface provided with that userdata, be it metatable with methods, or some other agreements.
If that userdata created by your code, then you either know what type of native object is there (knowing that some func generate or accept only specific type), or you can place type identifier as first bytes of userdata blob, so you can check that id and switch/cast userdata pointer to a specific class.
If that userdata created by someone's code - you can only rely on methods provided within its metatable (you can access it from native code), or just treat is as array of bytes, without possibly knowing actual type of data stored there. Or do some hackish guesses, making it working in some cases, and crashing badly if your guess wasn't correct.

Objective-C class as C pointer type

clang builtin function "__builtin_NSStringMakeConstantString" returns const NSConstantString*,
that is not an Objective-C retainable object.
I want to replace this function with my own, but there seems to be no way to declare NSConstantString* as non-Objective-C pointer in Objective-C++ (you can do it in Objective-C by using struct NSConstnatString*). I am sure, that this function returns NSConstantString, because the following two lines output PK16NSConstantString:
printf("%s\n", typeid(__builtin___NSStringMakeConstantString("foo")).name());
printf("%s\n", typeid(const NSConstantString*).name());
Whenever I try to execute the following code I get error "Cannot initialize a variable of type 'const NSConstantString *' with an rvalue of type 'const NSConstantString *'":
const NSConstantString* a = __builtin___NSStringMakeConstantString("foo");
Everything works OK if I add bridge cast, so this means that NSConstantString* is returned as "raw" Objective-C pointer, but I have to create a function that returns exactly the same result as "__builtin_NSStringMakeConstantString", so I have no option to use __bridge.
Whenever I try to return const NSConstantString* from a function, it is always returned as an Objective-C retainable pointer and there seems to be no way to declare it as C pointer except this:
typedef typeof __builtin___NSStringMakeConstantString("") rawNSConstnatStringPtr;
So the question is: Is there a way to declare a nonretainable pointer to NSConstantString* (without using typeof)?
You think _builtin__NSStringMakeConstant returns NSConstantString, because the compiler is tricking you.
I suggest you check out the clang source code: http://llvm.org/docs/GettingStarted.html#git-mirror
Then search the source code: git grep __builtin___NSStringMakeConstantString. You find that it's defined in include/clang/Basic/Builtins.def like this:
BUILTIN(__builtin___NSStringMakeConstantString, "FC*cC*", "nc")
The second argument is the function signature, and the comment at the top of the file explains what it means. The FC* part is the return type, and means “constant CFString const pointer”. That makes sense since CFString and NSString are toll-free bridged.
But it doesn't make sense because the error message specifically mentions NSConstantString. So git grep -w NSConstantString to see where that's coming from. You eventually find method ASTContext::getCFConstantStringType in lib/ast/ASTContext.cpp. This method creates a struct type declaration with the identifier NSConstantString, but it never adds the declaration to any scope (it doesn't call PushOnScopeChains or AddDecl). So the NSConstantString identifier can appear in diagnostics, but you cannot access the type by name in your source code. The NSConstantString type declared in NSString.h is, as far as the compiler is concerned, unrelated to this synthesized type.
Anyway, the important question is why you want to override __builtin___NSStringMakeConstantString, which you did not say. If it's because you want to use your own constant string class, you're going about it the wrong way.
I don't think you can override that function, because it is built in to the compiler. You would need to modify the compiler source code if you want to change its meaning.
Also, I don't think the compiler actually uses that function to create Objective-C string literals. Running git grep __builtin___NSStringMakeConstantString doesn't turn up any places where the compiler generates a call to it. The compiler handles #"string" syntax in lib/Parse/ParseObjc.cpp and lib/Sema/SemaExprObjC.cpp (look for methods named ParseObjCStringLiteral in both files). The compiler looks up the NSConstantString type by name (which means it should get the one from the NSString.h header file) and creates an instance of ObjCStringLiteral with that type.
You should be able to make it look up a different class for the constant string type (instead of NSConstantString) using the -fconstant-string-class command-line flag, but I don't know how well that works. This question implies that it might not work. Even if it does work, I think you're constrained to using the same memory layout as NSConstantString, in which case, why bother using a different class?

iOS circular dependencies between block definitions

In my iOS application I want to define two block types that take each other as parameters:
typedef void (^BlockA)(BlockB b);
typedef void (^BlockB)(BlockA a);
This fails compilation with 'Unknown type name BlockB in the first typedef (that makes sense).
I have a workaround which defines the types like this:
typedef void (^BlockA)(id);
typedef void (^BlockB)(BlockA a);
I then cast back to the BlockB type inside the BlockA definition, but at the expense of type safety.
I also looked at not using typedefs, but this results in an infinite nesting of expanded block definitions.
I know how to resolve circular dependencies for structs with forward declarations, but I can't see how to do this with blocks.
If there is no solution to the circular dependency, is there a way that I can restrict the parameter to BlockA to be any Block type rather than the generic id, this would give some level of type safety.
typedef does not define a "real" type. It's basically like a macro that expands out everywhere it's used. That's why typedefs cannot be recursive.
Another way to think about it is, typedefs are never necessary -- you can always take any piece of code with a typedef, and simply replace every occurrence of it with the underlying type (that's what the compiler does when you compile), and it will always work and be completely equivalent. Think about it -- how would you do it without a typedef? You can't. So you can't do it with a typedef either.
The only ways to do it are: use id as the argument type to erase the type like you're doing; or, encapsulate the block inside a "real" type like a struct or class. However, if you do it the latter way, you have to explicitly put the block into and extract the block out of the struct or class, which makes the code confusing. Also, struct is dangerous as struct is a scalar C type, and if you need to capture it by a block, it doesn't automatically memory-manage the objects inside the struct. As for class, defining a wrapping class is very verbose, and using it for this causes the allocation of an extraneous dummy object for every block it wraps.
In my opinion, using id like you're using is fine and is the cleanest way. However, keep in mind that if you need to have that block passed as id be captured by another inner block, that you should cast it back to the block type before being captured, as the capturing semantics is different for block and other object types (blocks are copied, whereas other objects are retained). Just casting it back to the block type at the earliest place will work.

Is it safe to pass a pointer to a method as a member of a record?

I want to implement a function in a dll that accepts a record as a parameter and this record as a few fields that hold pointers to callback routines. Would this be safe?
Yes, it's perfectly safe to have a pointer to a record that holds other pointers.
Your title mentions methods, though. DLLs rarely request method pointers because method pointers only exist in Delphi and C++ Builder. DLLs written expecting other tools to be able to use them will request ordinary function pointers, so please beware that method pointers are not compatible with pointers to standalone subroutines. The compiler will usually balk if you try to mix them, but type-casting can quell that error message. As a rule of thumb, if you're type-casting a function pointer or method pointer, you're doing something wrong. If your type declarations and your function declarations are correct, you won't need to type-cast.
Likewise, if you're using the # operator to create a function pointer or method pointer, you're probably doing it wrong. In most cases, the compiler can detect and assign compatible code pointers automatically, without you telling it that there's a pointer. Using # may suppress some of Delphi's type checking.
I don't see why not. I think all the usual issues with procedure/method pointers apply, so the object needs to exist if it's a method pointer.
It is safe but there are two issues that you should be aware about :
Records that declared as local variables are stored in the stack and they go away when the function returns. You should consider to allocate/dispose them on the heap with new/dispose functions.
If the DLL will be used by a program developed in other than delphi (or maybe even different versions of delpi), you have to use packed records.

Resources