Where and How to _Bridge

Where and how to __bridge

The documentation on the use of the bridge keyword can be found here. Specifically, I want to point out §3.2.4:

(__bridge T) op casts the operand to the destination type T. If T is a retainable object pointer type, then op must have a non-retainable pointer type. If T is a non-retainable pointer type, then op must have a retainable object pointer type. Otherwise the cast is ill-formed. There is no transfer of ownership, and ARC inserts no retain operations.

(__bridge_retained T) op casts the operand, which must have retainable object pointer type, to the destination type, which must be a non-retainable pointer type. ARC retains the value, subject to the usual optimizations on local values, and the recipient is responsible for balancing that +1.

(__bridge_transfer T) op casts the operand, which must have non-retainable pointer type, to the destination type, which must be a retainable object pointer type. ARC will release the value at the end of the enclosing full-expression, subject to the usual optimizations on local values.

The pointer you're being passed in (void*) is a non retainable pointer type, whereas your NSMutableArray is a retainable pointer type. This rules out __bridge_retained straight away. So the question is, to __bridge or to __bridge_transfer?

__bridge_transfer is typically used when you want the Objective-C pointer from a method that returns a CF Object that has been retained. For example, CFStringCreateWithFormat will return a retained CFString, but if you want an NSString from it, you need to __bridge_transfer between them. This will make ARC release the object that CF retained when appropriate. For example, NSString* str = (__bridge_transfer NSString*) CFStringCreateWithFormat(...);

Your code isn't doing that, you don't need to meddle with the ownership. Your main method is in control of its memory management, and is simply passing a reference to a method it calls (albeit indirectly, but it's all within the scope of main). As such, you would use __bridge.

But wait, when I use __bridge, my code gets memory access errors!?

Ah, this is an issue with the code you posted, and isn't in relation to the whole bridging discussion. You need to pass a void* to CGApplyPath, for your processing function _processPathElement. What you're passing is NSMutableArray**.

When you recast to the NSMutableArray*, you're actually casting a NSMutableArray**. This will cause the infamous EXC_BAD_ACCESS. You need to pass the pointer itself, not a pointer to a pointer. But, CGPathApply(path, pathPoints, _processPathElement) will not work, you cannot pass off a NSMutableArray* as a void*. What you need (ironically), is a bridge. For the same reasons as before, all you need is __bridge. See below the code, with the correct bridges in place, and working as expected:

#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>

void _processPathElement(void* info, const CGPathElement* element)
{
NSMutableArray *array = (__bridge NSMutableArray*) info;
switch (element->type)
{
case kCGPathElementMoveToPoint:
case kCGPathElementAddLineToPoint:
{
CGPoint point = element->points[0];
[array addObject:[NSValue valueWithCGPoint:point]];
break;
}
default:
break;
}
}

int main(int argc, char *argv[])
{
@autoreleasepool
{
//Create path
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint( path, NULL, 0, 0);
CGPathAddLineToPoint(path, NULL, 1, 0);
CGPathAddLineToPoint(path, NULL, 1, 1);
CGPathAddLineToPoint(path, NULL, 0, 1);
CGPathCloseSubpath(path);

NSMutableArray *pathPoints = [[NSMutableArray alloc] init];
CGPathApply(path, (__bridge void*)pathPoints, _processPathElement);

NSLog(@"Points:%@", pathPoints);
}
}

This will print out:

Points:(
"NSPoint: {0, 0}",
"NSPoint: {1, 0}",
"NSPoint: {1, 1}",
"NSPoint: {0, 1}"
)

When to use __bridge_transfer and __bridge

These keywords are used to tell to ARC system how to handle your non-objective-c pointers. In essence, if you use __bridge, you are telling to ARC not to deal with the ownership of the converted pointer because you will free it from non-objective-c code, most likely with a free() or a CFRelease... type function. __bridge_transfer, on the other hand, transfers the ownership to ARC and ARC will free your objective-c (and thus also the original non-objective-c) object via the standard release mechanism when the references to that object hits zero.

MySQL How can I make a better query to connect two tables through my bridge table?

I like to name the primary keys the same as the columns that reference them. So in your example, in the words table, you'd name the primary key ID_word. In the statements table, you'd name the primary key ID_statement.

The advantage is that you can make your SQL join a little more concise with the USING(...) syntax. This syntax assumes there's a column by that name in both tables of a join, and you want the join to match where the column is equal to the same column in the other table.

SELECT words.DATA FROM words 
JOIN bridge USING (ID_word)
JOIN statements USING (ID_statement)
WHERE statements.DATA = 'ja';

Also you don't need to run a subquery in your example. The rows in statement matching the IDs from the rows in statement where DATA='ja' are the same set as the rows in statement where DATA='ja'.

how would one describe the relationship here? one-to-many?

The relationship modeled by a bridge table is a many-to-many relationship. The specific data in your example doesn't show it, but it's possible that many different statements could reference the same word. What you do show is that each statement can reference many words.

How to update the Bridge table in SQL Server?

I want to change only Economics to Science for Group2.

You need another condition in your where clause, like so:

UPDATE tblSubjectGroupDetails SET subId = science_id
WHERE subGroupId = group_2_id
and subId = economics_id;

Just replace the IDs with the correct values.

Of course, this will not work (will generate a primary key constraint violation) if your Group2 has already a Science subject record in that table.

HQL Query when using Bridge Table?

You don't need to define the query. spring-data-jpa can autogenerate it based on method name.

    public interface UserRepository 
extends PagingAndSortingRepository<User, Long> {

public Page<User> findByAddressesAddressId(Long addressId,
Pageable pageable);
}

How do a query for a bridge longer or short than x?

Rather than using some rarely used tag that isn't even documented on the OSM wiki, you should calculate the actual length of a way using length(). See this Help OSM post for some ideas: https://gis.stackexchange.com/questions/325159/how-to-calculate-the-length-of-each-way-in-a-set-in-overpass-use-of-foreach-an

Working with numbers is described in this blog post: http://dev.overpass-api.de/blog/numbers.html

how to combine 2 or more bridge tables in a single query

SELECT p.first, p.last, r.name, s.name
FROM People p
LEFT JOIN People_Roles pr
ON pr.personID = p.id
INNER JOIN Roles r
ON pr.roleID = r.id
LEFT JOIN People_Skills ps
ON ps.personID = p.id
INNER JOIN Skills s
ON ps.skillID = s.id

This query will select you all the people, even those without Roles or Skills assigned.



Related Topics



Leave a reply



Submit