【问题标题】:Objective-C create a C array propertyObjective-C 创建一个 C 数组属性
【发布时间】:2013-05-17 10:31:32
【问题描述】:

我想创建一个由 CGRect 指针数组构成的属性,数字没有在开头定义,所以我想创建一个指向包含该数组开​​头的内存区域的指针的指针。这似乎很困难,我已经看到了不同的答案并以此为基础。
到目前为止,我已经写过:

@interface ViewController ()
@property (assign) CGRect * rectArray;
@property (strong, nonatomic) NSArray * hotspots;
@end

@implementation ViewController



- (CGRect *) createRectArray {
    int count = _hotspots.count;
    _rectArray = malloc(sizeof(CGRect*)*count);
    for (int i = 0; i<count; i++) {
        CGRect currentFrame = ((UIView*)_hotspots[i]).frame;
        _rectArray[i] = &currentFrame;
    }

    return _rectArray;
}
@end

但编译器抱怨告诉我分配不正确。

我猜可能正确的变量不是CGRect * rectArray,而是双重间接CGRect ** rectArray。
那是对的吗?
[更新]
实际上我想做的事情没有意义......因为属性 -frame 返回 CGRect 的副本而不是指向它的指针,所以我直接快速访问它的想法已经不复存在了。

【问题讨论】:

  • 这是完整的类定义吗?好像少了点什么……
  • 当然不是...我已经删除了所有不必要的方法
  • @Andrea 你想做什么“打破封装”;它暴露了 UIView 内部实现的细节,而不是正确使用提供的访问器。您不应该存储指向访问器返回内容的指针,您应该始终直接使用访问器。
  • 顺便说一句,UIView 上的frame 不是一块内存。 UIView 仅存储 boundscenterframe 只是一个方便的访问器,它将两个属性合并在一起。
  • @wilsonmichaelpatrick 是的,这在概念上是错误的,我想那是因为我生病了,而且我的思想正在绊倒。谢谢你的评论

标签: objective-c c memory


【解决方案1】:

以下代码正确访问rectArray

@interface ViewController ()
//array of pointers 
@property (assign) CGRect **rectArray;
@property (strong, nonatomic) NSArray * hotspots;
@end

@implementation ViewController


- (CGRect **) createRectArray {
    int count = _hotspots.count;
    _rectArray = malloc(sizeof(CGRect*)*count);

    for (int i = 0; i<count; i++) {
        //this will never work, the frame returned from UIView is a temporary which will get released!
        CGRect currentFrame = ((UIView*)_hotspots[i]).frame;
        _rectArray[i] = &currentFrame;
    }

    return _rectArray;
}

- (void)dealloc {
   free(_rectArray);
}
@end

但是,正如我在 cmets 中所写的那样,这是行不通的。 [UIView frame] 返回一个 C 结构。这与原始变量(NSIntegerlong 等)的行为相同。它被复制了。 &amp;currentFrame 是对本地堆栈变量的引用,当代码超出范围时(for 迭代结束,方法结束),它将被释放。它不会做你所期望的。访问存储的指针会使您的应用程序崩溃。

您所期望的功能可以通过以下两种方法轻松实现

- (void)setFrame:(CGRect)frame forHotspotAtIndex:(NSUinteger)index {
    UIView* hotspot = [self.hotspots objectAtIndex:index];
    hotspot.frame = frame;
}

- (CGRect)frameForHotspotAtIndex:(NSUinteger)index {
    UIView* hotspot = [self.hotspots objectAtIndex:index];
    return hotspot.frame;
}

【讨论】:

  • 是的@Suthan 你是完全正确的,我不知道我为什么要搞砸这个,在概念上是错误的。谢谢
【解决方案2】:

如果您正在分配一个 CGRect 数组,malloc(sizeof(CGRect*)*count) 是错误的,因为您正在尝试分配一个指向 CGRect 的指针数组。
此外,当我们将 CGRect 分配给数组时,我们不需要获取它的指针,_rectArray[i] = currentFrame 应该可以正常工作。

以下代码应该适合您:

@interface ViewController ()
@property (assign) CGRect * rectArray;
@property (strong, nonatomic) NSArray * hotspots;
@end

@implementation ViewController

- (CGRect *) createRectArray {
    int count = _hotspots.count;
    _rectArray = malloc(sizeof(CGRect)*count);
    for (int i = 0; i<count; i++) {
        CGRect currentFrame = ((UIView*)[_hotspots objectAtIndex:i]).frame;
        _rectArray[i] = currentFrame;
    }

    return _rectArray;
}
@end

【讨论】:

  • 谢谢.. 但实际上我想要一个指向 CGRect 的指针数组,我也会尝试。
猜你喜欢
  • 2010-10-03
  • 1970-01-01
  • 2011-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多