Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A strange type casting in Objective-c

I found a demo snippets which used type casting like this:(int)view.'view' is a pointer of UIView's object. I have never known it can be use to cast type. Someone can help me to explain it? paste code here

- (CGPoint)accelerationForView:(UIView *)view
{
    // return
    CGPoint accelecration;

    // get acceleration
    NSValue *pointValue = [self._accelerationsOfSubViews objectForKey:
                                     [NSNumber numberWithInteger:(int)view]];
    if (pointValue == nil) {
        accelecration = CGPointZero;
    }
    else {
        [pointValue getValue:&accelecration];
    }

    return accelecration;
}

- (void)willRemoveSubview:(UIView *)subview
{
    [self._accelerationsOfSubViews removeObjectForKey:
                         [NSNumber numberWithInt:(int)subview]];
}
like image 726
Tab Avatar asked Apr 21 '26 17:04

Tab


2 Answers

[NSNumber numberWithInteger:(int)view]

view is not an object of type UIView, it's a pointer of type UIView*. The code above casts the pointer to an int for the purpose of storing it in a NSNumber, apparently so that it can be used as a key in a dictionary. Since pointers themselves aren't objects, you can't use them as dictionary keys. But if you create an instance of NSNumber from the pointer, you can use the resulting object as a key. People do this sort of thing sometimes to keep track of some information that they want to associate with a number of objects (like views) that's not stored in the objects themselves (like acceleration).

As I mention in my comment below, the code here uses +numberWithInteger:, which is good because that method takes a NSInteger, which will be 32 bits on a 32-bit system and 64 bits on a 64-bit system. However, the author then nullified that good decision by casting to int, which will generally be 32 bits even on a 64-bit system. The cast should really be to NSInteger, like this:

[NSNumber numberWithInteger:(NSInteger)view]
like image 65
Caleb Avatar answered Apr 23 '26 07:04

Caleb


(NOTE: This is builds on @Caleb's answer, assuming the original code is trying to associate an acceleration value with a UIView)

I would add an acceleration property to UIView via a category, like this:

UIView+acceleration.h:

@interface UIView ( Acceleration )
@property ( nonatomic ) CGPoint acceleration ;
@end

UIView+acceleration.m

#import <objc/runtime.h>

@implementation UIView ( Acceleration )

const char * kAccelerationKey = "acceleration" ; // should use something with a prefix just in case

-(void)setAcceleration:(CGPoint)acceleration
{
    objc_setAssociatedObject( self, kAccelerationKey, [ NSValue valueWithCGPoint:acceleration ], OBJC_ASSOCIATION_RETAIN_NONATOMIC ) ;
}

-(CGPoint)acceleration
{
    return [ objc_setAssociatedObject( self, kAccelerationKey ) CGPointValue ] ;
}

@end

Delete -accelerationForView: and -willRemoveSubview: and use view.acceleration = <some point> or <some point> = view.acceleration.

like image 39
nielsbot Avatar answered Apr 23 '26 06:04

nielsbot



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!