Tôi có một mảng con trỏ 2D cho các cá thể Objective-C để theo dõi các đối tượng trò chơi trên lưới bản đồ. Bây giờ tôi đang chuyển mã của tôi sang ARC và Xcode đã chỉ ra lỗi. Tôi biết con trỏ đến các đối tượng không được phép làm thành viên cấu trúc, nhưng điều này đã khiến tôi (gần như) mất cảnh giác.Mảng con trỏ kiểu C cho các đối tượng Objective-C trong ARC
Tôi hiểu lý do đằng sau sự ép ARC, nhưng:
Tôi không có khả năng chi phí của mảng khách quan-C khi nhìn lên các đối tượng trong lưới, và
Đối tượng bản thân chúng đã thuộc sở hữu của một thanh vectơ
NSArray
được định nghĩa trong cùng một lớp có lưới kiểu C làm ngà; mảng kiểu c chỉ là một lối tắt có cấu trúc thuận tiện. Hơn nữa, khi các đối tượng được lấy ra khỏi việc sở hữuNSArray
, tôi đặt khe lưới tương ứng thànhNULL
.
Đó là, các mảng 2D (lưới) chỉ là một tập hợp các nhanh (nhưng câm) các đối tượng một cách an toàn giữ lại ở một nơi khác con trỏ (các NSArray
Ivar).
Có cách nào để loại bỏ điều này bằng cách sử dụng phôi không? Ví dụ, xác định và alloc lưới của tôi là:
void*** _grid;
thay vì
MyMapObjectClass*** _grid
và sử dụng (một cách thích hợp bắc cầu) phôi giữa void*
< ->MyMapObjectClass*
khi đặt hoặc nhận các con trỏ trong mỗi khe?
EDIT: Vì vậy, đây là cách tôi giải quyết nó
tôi đã thay đổi tờ khai Ivar như đã mô tả ở trên. Ngoài ra, khi thiết lập một mục của lưới nhìn lên tôi, tôi đã làm điều này:
// (Done **Only Once** at map initialization)
// _objectArray is an instance of NSMutableArray
MyMapObjectClass* mapObject = [[MyMapObjectClass alloc] init];
// ...configure map object, etc...
// Add to Obj-C array:
[_objectArray addObject:mapObject];
// Add pointer to 2D C array:
_grid[i][j] = (__bridge void*)mapObject;
Khi truy cập vào các đối tượng tại (x, y), tôi làm ngược lại:
MyMapObjectClass* object = (__bridge MyMapObjectClass*) _grid[x][y];
[object performSomeMethod];
// etc...
Khi tháo đối tượng từ bản đồ, tôi làm điều này:
MyMapObjectClass* object = (__bridge MyMapObjectClass*) _grid[x][y];
[_objectArray removeObject:object];
_grid[x][y] = NULL;
Đối tượng bản đồ được tạo một lần vào đầu trò chơi và bị xóa theo tiến trình trò chơi. Nếu tôi cần phải thay thế một đối tượng bản đồ cho người khác, tôi sẽ làm điều này:
MyMapObjectClass* oldObject = (__bridge MyMapObjectClass*) _grid[x][y];
// (should mark as weak?)
[_objectArray removeObject:oldObject];
_grid[x][y] = NULL;
MyMapObjectClass* newObject = [[MyMapObjectClass alloc] init];
[_objectArray addObject:newObject];
_grid[x][y] = (__bridge void*)newObject;
mà dòng mã mà ARC đang chỉ ra ở đâu? –
Xcode dường như không chỉ ra tất cả các lỗi cùng một lúc, mà thay vào đó là các lô 4-12. Bạn sửa chữa một số, và những cái tiếp theo xuất hiện trong kiểm tra sau đây. Lỗi đầu tiên xuất hiện trong khai báo ivar của mảng C. Và bây giờ, mọi phép gán hoặc so sánh giữa con trỏ obj-c và void * đang được báo hiệu. Tôi đang sửa chữa nó ngay bây giờ, và có vẻ như __bridge sẽ hoạt động ... –
Thật lạ lùng, một số phôi được 'đề xuất' bởi tính năng tự động sửa lỗi của Xcode, nhưng một số chỉ được đánh dấu là lỗi. –