Skip to content

Commit e4844a4

Browse files
committed
Reevaluate NSArray ownership
1 parent a03e2de commit e4844a4

File tree

1 file changed

+31
-13
lines changed

1 file changed

+31
-13
lines changed

objc2_foundation/src/array.rs

+31-13
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ pub trait INSArray: INSObject {
144144
self.objects_in_range(0..self.count())
145145
}
146146

147+
// TODO: Take Id<Self, Self::ItemOwnership> ?
147148
fn into_vec(array: Id<Self, Owned>) -> Vec<Id<Self::Item, Self::ItemOwnership>> {
148149
array
149150
.to_vec()
@@ -188,14 +189,27 @@ pub trait INSArray: INSObject {
188189
}
189190
}
190191

192+
/// TODO
193+
///
194+
/// You can have a `Id<NSArray<T, Owned>, Owned>`, which allows mutable access
195+
/// to the elements (without modifying the array itself), and
196+
/// `Id<NSArray<T, Shared>, Shared>` which allows sharing the array.
197+
///
198+
/// `Id<NSArray<T, Owned>, Shared>` is possible, but pretty useless.
199+
/// TODO: Can we make it impossible? Should we?
191200
pub struct NSArray<T, O: Ownership> {
192201
item: PhantomData<Id<T, O>>,
193202
}
194203

195204
object_impl!(NSArray<T, O: Ownership>);
196205

197206
impl<T: INSObject, O: Ownership> INSObject for NSArray<T, O> {
198-
type Ownership = Shared;
207+
/// The `NSArray` itself (length and number of items) is always immutable,
208+
/// but we would like to know when we're the only owner of the array, to
209+
/// allow mutation of the array's items.
210+
///
211+
/// We only implement `INSCopying` when `O = Shared`, so this is safe.
212+
type Ownership = O;
199213

200214
fn class() -> &'static Class {
201215
class!(NSArray)
@@ -207,6 +221,8 @@ impl<T: INSObject, O: Ownership> INSArray for NSArray<T, O> {
207221
type ItemOwnership = O;
208222
}
209223

224+
// Copying only possible when ItemOwnership = Shared
225+
210226
impl<T: INSObject> INSCopying for NSArray<T, Shared> {
211227
type Output = NSArray<T, Shared>;
212228
}
@@ -340,6 +356,8 @@ impl<T: INSObject, O: Ownership> INSArray for NSMutableArray<T, O> {
340356

341357
impl<T: INSObject, O: Ownership> INSMutableArray for NSMutableArray<T, O> {}
342358

359+
// Copying only possible when ItemOwnership = Shared
360+
343361
impl<T: INSObject> INSCopying for NSMutableArray<T, Shared> {
344362
type Output = NSArray<T, Shared>;
345363
}
@@ -367,19 +385,19 @@ mod tests {
367385

368386
use super::{INSArray, INSMutableArray, NSArray, NSMutableArray};
369387
use crate::{INSObject, INSString, NSObject, NSString};
370-
use objc2::rc::{Id, Shared};
388+
use objc2::rc::{Id, Owned};
371389

372-
fn sample_array(len: usize) -> Id<NSArray<NSObject, Shared>, Shared> {
390+
fn sample_array(len: usize) -> Id<NSArray<NSObject, Owned>, Owned> {
373391
let mut vec = Vec::with_capacity(len);
374392
for _ in 0..len {
375-
vec.push(NSObject::new().into());
393+
vec.push(NSObject::new());
376394
}
377395
NSArray::from_vec(vec)
378396
}
379397

380398
#[test]
381399
fn test_count() {
382-
let empty_array = NSArray::<NSObject>::new();
400+
let empty_array = NSArray::<NSObject, Owned>::new();
383401
assert!(empty_array.count() == 0);
384402

385403
let array = sample_array(4);
@@ -393,7 +411,7 @@ mod tests {
393411
assert!(array.first_object().unwrap() == array.object_at(0));
394412
assert!(array.last_object().unwrap() == array.object_at(3));
395413

396-
let empty_array: Id<NSArray<NSObject>, _> = INSObject::new();
414+
let empty_array: Id<NSArray<NSObject, Owned>, _> = INSObject::new();
397415
assert!(empty_array.first_object().is_none());
398416
assert!(empty_array.last_object().is_none());
399417
}
@@ -425,13 +443,13 @@ mod tests {
425443
assert!(all_objs.len() == 4);
426444
}
427445

428-
// #[test]
429-
// fn test_into_vec() {
430-
// let array = sample_array(4);
431-
//
432-
// let vec = INSArray::into_vec(array);
433-
// assert!(vec.len() == 4);
434-
// }
446+
#[test]
447+
fn test_into_vec() {
448+
let array = sample_array(4);
449+
450+
let vec = INSArray::into_vec(array);
451+
assert!(vec.len() == 4);
452+
}
435453

436454
#[test]
437455
fn test_add_object() {

0 commit comments

Comments
 (0)