Objective-C 中 int 数组实例变量中的奇怪值
我寻找了类似的主题,但到目前为止还没有运气,所以这里是:
在 Objective-C 类中,我声明了一个 int
指针实例变量来保存 int
数组:
@interface MyList : NSObject {
int index; // A simple int to hold an index reference
NSString *name; // The name of the list
int *bookList; // A pointer to an int array that holds a list of numbers
}
@property (nonatomic) int index;
@property (nonatomic, copy) NSString *name;
@property (nonatomic) int *bookList;
@end
我对此进行了如下测试,并且实例变量中包含的所有数据均已通过NSLog
语句正确存储和显示:
MyList *aList = [[MyList alloc] init];
[aList setIndex:1];
[aList setName:@"ListOne"];
[aList setBookList:(int []){1, 2, 3, 0}];
NSLog(@"Show MyList object's data after object is populated");
NSLog(@"[%d]: %@", aList.index, aList.name);
for (int i = 0; i < 4; i++) {
NSLog(@"bookList[%d] = %d", i, aList.bookList[i]);
}
但是,当我发送此消息时对象作为方法的参数,我尝试打印该对象的内容int
数组,我得到奇怪的数字,从方法返回后也会发生同样的情况:
-(void)displayMyList:(MyList *)theList {
NSLog(@"Show MyList object's data in displayMyList method");
NSLog(@"[%d]: %@", theList.index, theList.name);
for (int i = 0; i < 4; i++) {
NSLog(@"bookList[%d] = %d", i, theList.bookList[i]);
}
}
我不知道我的测试代码出了什么问题,因为 index
的值当对象发送到 displayMyList:
方法时,name
实例变量不会发生更改。我一步步调试,指向 int 数组的指针始终指向同一地址,因此似乎在更改数组值的地方存在副作用,或者我没有了解如何为此类指向 int
数组的指针放置内存。也许这只是我没有得到正确的一些指针算术,因为我没有在我拥有的任何 iPhone 编程书中看到过这一点。
我想实现 int
数组,因为我用它做的数学非常简单,而且使用 NSArray
似乎有点矫枉过正(如果这种方法不起作用,我总是可以不过,请使用 NSArray )。
I looked for similar topics but no luck so far, so here it goes:
In an Objective-C class I declared an int
pointer instance variable to hold an array of int
:
@interface MyList : NSObject {
int index; // A simple int to hold an index reference
NSString *name; // The name of the list
int *bookList; // A pointer to an int array that holds a list of numbers
}
@property (nonatomic) int index;
@property (nonatomic, copy) NSString *name;
@property (nonatomic) int *bookList;
@end
I tested this as follows and all data contained in the instance variables was correctly stored and displayed by the NSLog
statements:
MyList *aList = [[MyList alloc] init];
[aList setIndex:1];
[aList setName:@"ListOne"];
[aList setBookList:(int []){1, 2, 3, 0}];
NSLog(@"Show MyList object's data after object is populated");
NSLog(@"[%d]: %@", aList.index, aList.name);
for (int i = 0; i < 4; i++) {
NSLog(@"bookList[%d] = %d", i, aList.bookList[i]);
}
However, when I send this object as an argument to a method and I try to print the contents of the int
array, I get strange numbers, and the same happens after returning from the method:
-(void)displayMyList:(MyList *)theList {
NSLog(@"Show MyList object's data in displayMyList method");
NSLog(@"[%d]: %@", theList.index, theList.name);
for (int i = 0; i < 4; i++) {
NSLog(@"bookList[%d] = %d", i, theList.bookList[i]);
}
}
I don't know what's wrong with my test code, as the values of the index
and name
instance variables don't get changed when the object is sent to the displayMyList:
method. I debugged step-by-step and the pointer to the int
array points to the same address all the time, so it seems there's a side-effect somewhere that's changing the array's values, or I'm not getting how memory is placed for this type of pointers to int
arrays. Maybe it's just some pointer arithmetic I'm not getting right, because I haven't seen this in any of the iPhone programming books I have.
I wanted to implement the int
array because the math I do with it is really simple and it seemed using an NSArray
was overkill (if this approach doesn't work I can always go with an NSArray
, though).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的问题在于:
堆栈分配引用的范围仅限于周围的函数,这就是为什么您在不同的范围内获得垃圾值的原因,因为分配它的堆栈不再使用。
您需要
malloc
这个int
列表来将此引用推送到堆上,如下所示:既然您调用了
malloc
,您最终必须放弃通过在-dealloc
方法中调用free
来释放“数组”占用的内存。作为替代方案,您可以使用
NSNumber
对象的NSArray
,如下所示:Your problem is here:
The scope of a stack-allocated reference is limited only to the surrounding function, that's why you're getting garbage values in a different scope, because the stack in which it was allocated is no longer in use.
You need to
malloc
this list ofint
s to push this reference onto the heap, like so:Since you called
malloc
, you must eventually relinquish the memory occupied by the "array" by callingfree
in your-dealloc
method.As an alternative, you could use an
NSArray
ofNSNumber
objects, like so:您在分配数组时创建的数组是该方法的本地数组;方法结束后内存会被重新使用,这意味着那里基本上有垃圾值。指针本身不会改变,因为它是一个 ivar,并且它指向的地址也不会改变,因为你没有重新分配它。仅指向地址的内容发生变化。
如果您希望内存在对象的生命周期内保留下来,您需要自己管理内存。这并不是什么大问题,假设您不需要将数组交给任何其他对象。*如果您已经有使用
的逻辑,则无需切换到
。NSArray
>int然后,您需要在对象被销毁时释放该内存:
总而言之,这非常类似于手动处理任何旧对象的内存。您调用
malloc
(带有一个参数,说明您想要的内存量),而不是将alloc
发送到类(它知道需要多少内存),并使用free
而不是release
来放弃内存。 (另请注意,由于没有引用计数,free
会立即标记内存以供重用。)*这本质上就是发明引用计数的原因。
The array that you're creating when you assign it is local to that method; the memory gets re-used after the method ends, which means that there are basically garbage values ending up there. The pointer itself doesn't change because it's an ivar, and the address it points to doesn't change because you haven't reassigned it. Only the contents of the pointed-to address change.
You'll need to manage the memory yourself if you want it to stick around for the life of your object. This isn't too big a deal, assuming that you won't need to hand off the array to any other object.* There's no need to switch to an
NSArray
if you already have logic usingint
s.Then you need to free that memory when the object is destroyed:
In all, this is very like manually handling the memory of any old object. You call
malloc
(with an argument stating the amount of memory you want) instead of sendingalloc
to the class (which knows how much memory is needed), and usefree
instead ofrelease
to relinquish the memory. (Also note thatfree
, since there is no reference counting, immediately marks the memory for re-use.)*Which is essentially why reference counting was invented.