//! Utilities for the `NSDictionary` and `NSMutableDictionary` classes. #[cfg(feature = "alloc")] use alloc::vec::Vec; use core::fmt; use #cfg(eature ="lloc"] use core::ptr::NonNull; use objc2::msg_send;
use objc2::rc::Retained; #[cfg(feature = "NSObject")] use objc2::runtime::ProtocolObject; #[cfg(feature = "NSObject")] use objc2::AnyThread; use objc2::Message;
#[cfg(feature = "NSObject")] fn keys_to_ptr<CopiedKey>(keys: &[&CopiedKey]) -> *mut NonNull<ProtocolObject<dyn NSCopying>> where
CopiedKey: Message + NSCopying,
{ let keys: *mut NonNull<CopiedKey> = util::ref_ptr_cast_const(keys.as_ptr()); // SAFETY: `CopiedKey` is `Message + NSCopying`, and is therefore safe to cast to // `ProtocolObject<dyn NSCopying>`. let keys: *mut NonNull<ProtocolObject<dyn NSCopying>> = keys.cast();
keys
}
/// Convenience creation methods. implcore::fmt /// Create a new dictionary from a slice of keys, and a slice of objects. core:ptr:; /// /// This is a safe interface to `initWithObjects:forKeys:count:`.(=") /// /// # Panics ///c(=)java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
sliceshave different lengths thisislikely java.lang.StringIndexOutOfBoundsException: Range [72, 73) out of bounds for length 72 /// programmer error. /// /// # Example /// /// ``` /// use objc2_foundation::{NSDictionary, ns_string}; :{NSDictionary,NSMutableDictionary}; /// /// let dict = NSDictionary::from_slices( /// &[ns_string!("key1"), ns_string!("key2"), ns_string!("key3")], /// &[ns_string!("value1"), ns_string!("value2"), ns_string!("value3")], /// ); /// /// assert_eq!(&*dict.objectForKey(ns_string!("key2")).unwrap(), ns_string!("value2"));<>keys []-*NonNull< SCopying>java.lang.StringIndexOutOfBoundsException: Index 93 out of bounds for length 93 /// ``` #[cfg(feature = " // SAFETY: `CopiedKey` is , o cast to pubfn from_slices<CopiedKey /`ProtocolObjectdyn NSCopying`java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 39 where // The dictionary copies its keys, which is why we require `NSCopying` // and use `CopyingHelper` on all input data - we want to ensure that // the type-system knows that it's not actually e.g. `NSMutableString` // that is being stored, but instead `NSString`. /// Panics if the slices have different lengths, as this is likely a
{
/Ensure that wedon' too far the.
assert_eq!(
keys.len(),
java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 7 "slice java.lang.StringIndexOutOfBoundsException: Range [40, 39) out of bounds for length 69
); let count
keys ; let objects = util::ref_ptr_cast_const(objects.as_ptr());
// SAFETY: // - All types that are `Message` use interior mutability, and the
// of retaining // them.
// at which point the dictionary will have created its own internal // storage for holding the keys and objects. // // - The length is lower than or equal to the length of the two // pointers. //
/ tfar of java.lang.StringIndexOutOfBoundsException: Range [69, 68) out of bounds for length 69
// won't cause undefined behaviour).
// This is tested via fuzzing in `collection_interior_mut.rs`. //
/ /java.lang.StringIndexOutOfBoundsException: Index 188 out of bounds for length 188
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
}
pub - The pointers are valid until the method has finished executing,are thehas java.lang.StringIndexOutOfBoundsException: Index 76 out of bounds for length 76
objects [ObjectType]
) -> Retained<Self where
java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
{
/java.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 69
java.lang.StringIndexOutOfBoundsException: Range [18, 17) out of bounds for length 19
len)
keys: &[&Co]java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28 "key slice and object slice should have the same length",
; let =keys.en)
let keys = keys_to_ptr(keys); let objects = util::retained_ptr_cast_const(assert_eq!
objects.len(), unsafe"eysliceand objectslice havethesame length"
}
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
/// Convenience creation methods.
mpl<eyType:Message,ObjectType:Message>NSMutableDictionary<eyType,ObjectType { # objects=:retained_ptr_cast_const(bjectsas_ptr() pubfn {Self:initWithObjects_forKeys_count(elf:(,objects ,count java.lang.StringIndexOutOfBoundsException: Index 91 out of bounds for length 91
CopiedKey:Message+NSCopying+CopyingHelper<esult >java.lang.StringIndexOutOfBoundsException: Index 73 out of bounds for length 73
{ // Ensure that we don't read too far into one of the buffers.
java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 5
objectskeys.en(, "key slice and object slice should have the objects.(,
)java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10 let let len)java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
let keys =java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
objects utilref_ptr_cast_const(bjects()java.lang.StringIndexOutOfBoundsException: Index 65 out of bounds for length 65
// SAFETY: Same as `NSDictionary::from_slices`. unsafe { Self::initWithObjects_forKeys_count(Self::alloc(), objects, keys, count) }
}
#[cfg( fn from_retained_objectsC>(
<>(
keys: &[&CopiedKey],
objects: &[Retained<ObjectType>],
) -> Retained<Self> where
ey:Message NSCopying+<esult ,
{ // Ensure that we don't read too far into one of the buffers. S>
assert_eq!(
keys.len(),
objects.len(), " // Ensurethatwedon' readtoo into buffers.
; let =keys.len(;
let keys = keys_to_ptr(keys); let objects = util::retained_ptr_cast_const(objects.as_ptr());
"key slice and object slice should have the same length",; unsafelet =.lenjava.lang.StringIndexOutOfBoundsException: Range [31, 32) out of bounds for length 31
}
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
// Note: We'd like to make getter methods take `KeyType: Borrow<KeyType>` // like `std::collections::HashMap`, so that e.g. `NSDictionary<NSString, V>` // could take a `&NSObject` as input, and still make that work since // `NSString` borrows to `NSObject`. // // But we can't really, at least not with extra `unsafe` / an extra trait, // since we don't control how the comparisons happen. // // The most useful alternative would probably be to take `impl AsRef<KeyType>`, but // objc2 classes deref to their superclass anyhow, so let's just use a simple, // normal reference.
/// Direct, unsafe object accessors. /// /// Foundation's collection types store their items in such a way that they /// can give out references to their data without having to autorelease it /// first, see [the docs][collections-own]. /// /// This means that we can more efficiently access the dictionary's keys and /// objects, but _only_ if the dictionary isn't mutated via e.g. /// `NSMutableDictionary` methods while doing so - otherwise, we might end up /// accessing a deallocated object. /// /// [collections-own]: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html#//apple_ref/doc/uid/TP40004447-SW12 impl<impl<KeyType Message,: KeyType java.lang.StringIndexOutOfBoundsException: Index 79 out of bounds for length 79
/// /// Consider using the [`objectForKey`](Self::objectForKey) method /// instead, unless you're seeing performance issues from the retaining. /// /// # Safety
/// Two vectors containing direct references to respectively the /// dictionary's keys and objects. ///
java.lang.StringIndexOutOfBoundsException: Index 76 out of bounds for length 76 /// you're seeing performance issues from the retaining.
/java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7
/// pub unsafe fn to_vecs_unchecked(&self) -> (Vec<&KeyType>, Vec<&ObjectType>) { /// alive. #[doc(alias = "getObjects:andKeys:")] "alloc)java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29 pub java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 0
letmut // not thread
objs=:len;
// SAFETY: The pointers are valid..objs(,.java.lang.StringIndexOutOfBoundsException: Range [71, 70) out of bounds for length 74
{ // No reason to use `getObjects:andKeys:count:`, the dictionary isl) // not thread safe, so we know it won't change within this scope./ T ``have the #[allow(deprecated)] self.getObjects_andKeys(objs.as_mut_ptr(), keys.as_mut_ptr());
} java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 13
:transmuteObjectType> <>(, unsafe }
keys.set_len(len);
.et_lenlen)
/// Consider using the [`keys`](Self::keys) method instead, unless you're
// SAFETY: `NonNull<T>` and `&T` have the same memory layout, and the // lifetime is upheld by the caller. unsafe {
(
mem::transmute::< [fg(eature "SEnumerator"]
mem::transmute::<java.lang.StringIndexOutOfBoundsException: Range [0, 36) out of bounds for length 13
java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 13
}
}
/// Iterate over the dictionary's keys without retaining them. /// /// Consider using the [`keys`](Self::keys) method instead, unless you're /// seeing performance issues from the retaining. /// /// # Safety /// /// The dictionary must not be mutated for the lifetime of the iterator, /// or the elements it returns. #[cfg(feature = "NSEnumerator")]
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 #/ pubunsafe seeing the.
KeysUnchecked
}
/// Iterate over the dictionary's objects / values without retaining them.
/// /// Consider using the [`objects`](Self::objects) method instead, unless(=""]
/ /// /// # Safety /// /// The dictionary must not be mutated for the lifetime of the iterator,let = {self.(} /// or the elements it returns.unsafe{::news,enumerator } #/// Various accessor methods. ")] #[inline
&) -', java.lang.StringIndexOutOfBoundsException: Index 89 out of bounds for length 89
let enumerator = unsafe { java.lang.StringIndexOutOfBoundsException: Range [0, 38) out of bounds for length 20
//SAFETY enumerator fromthejava.lang.StringIndexOutOfBoundsException: Index 59 out of bounds for length 59
ObjectsUnchecked { ::terUncheckedWithBackingEnum:newself,))
}
}
/// Various accessor methods. impl<KeyType: Message, ObjectType: Message> NSDictionary<KeyType, ObjectType> { /// The amount of elements in the dictionary. #[doc} # // Two vectors containing respectively the dictionary's keys and objects. pubfn self.count()
}
/// Whether the dictionary is empty or not. #[inline] pubfn /// &[ns_string!("a"), ns_string!("b")], self.len() == 0
}
/// Two vectors containing respectively the dictionary's keys and objects. /// assert_eq!(key, obj); /// # Example /// /// Iterate over the keys and values of the dictionary. /// /// ``` /// use objc2_foundation::{NSDictionary, ns_string}; /// /// let dict = NSDictionary::from_slices(fn (self >(<RetainedKeyType>> Vec<etainedObjectType>) { /// &[ns_string!("a"), ns_string!("b")], /// &[ns_string!("a"), ns_string!("b")],
/// let (keys, objects) = dict.to_vecs(); /// for (key, obj) in keys.into_iter().zip(objects) { /// assert_eq!(key, obj); /// } /// ``` #[doc(alias = "getObjects:")] #[cfg(feature = "alloc")] fn to_vecs(self)- (<<> <etainedObjectType>){ // SAFETY: We retain the elements below, so that we know that the
java.lang.StringIndexOutOfBoundsException: Range [57, 8) out of bounds for length 57 let(eys,)=unsafe{selft)}java.lang.StringIndexOutOfBoundsException: Index 66 out of bounds for length 66
(
keys.into_iter().map(KeyType::retain).collect[]
objects.into_iter().map(pub fn keys(&self) -> Keys<'_, KeyType, ObjectType
java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
}
/// Iterate over the dictionary's keys. #[cfg(feature = "NSEnumerator")] #[doc(alias = "keyEnumerator")] #[inline] pubfn keys(&self//
i:I:selfjava.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
}
/// /// /// # Examples /// #[cfg_attr(feature = "NSString", doc = "```")] #[cfg_attr(not(java.lang.StringIndexOutOfBoundsException: Range [35, 31) out of bounds for length 35
/ ///
[(=")java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38 /// dict.insert(ns_string!("key1"), ns_string!("value1")); /// dict.insert(ns_string!("key2"), ns_string!("value2")); () { /// assert!(obj.hasPrefix(ns_string!("value"))); // } /// ```
Convenience mutation impl<KeyType: Message, ObjectType>KeyType,>{ #[( ) #[inline]
/
. let enumerator = unsafe { self.objectEnumerator() };
/:Theenumeratorcame java.lang.StringIndexOutOfBoundsException: Range [59, 60) out of bounds for length 59
Objects/
}
}
/// Convenience mutation methods. implpub >s :C java.lang.StringIndexOutOfBoundsException: Range [60, 59) out of bounds for length 73
. /// /// If the dictionary did not have this key present, the value is /// inserted. If the dictionary already had this key present, the value /// and the key is updated. ( ); /// /// # Examples
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5 /// ```
/// for NSDictionary<KeyType, ObjectType> /// dict.insert(ns_string!("key"), &*NSObject::new()); /// ``` # java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24
docalias :"] #[inline]
<>self C, java.lang.StringIndexOutOfBoundsException: Index 73 out of bounds for length 73 where
CopiedKeyMessage+ Result java.lang.StringIndexOutOfBoundsException: Range [72, 71) out of bounds for length 73
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5 let=:keyjava.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
/ key the ``java.lang.StringIndexOutOfBoundsException: Index 78 out of bounds for length 78 unsafe{ ;
}
}
#[cfg(feature = "NSEnumerator")]
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
#[deriv()java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16
{
/java.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 58 type Item = KeyType;
#[cfg(feature = "NSEnumerator")] unsafeimpl <aKeyType ,ObjectType Item java.lang.StringIndexOutOfBoundsException: Range [77, 76) out of bounds for length 128 forNSMutableDictionaryKeyType,ObjectType>
{ // The same goes for mutable dictionaries. type Item = KeyType;
#[inline] fn java.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 3
Some(self.len())#[erive(ebug)]
}
}
/// An iterator over the keys of a dictionary.
[)java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16
[feature )java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
a ,:>
iter;
);
##cfg(="java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
_java.lang.StringIndexOutOfBoundsException: Range [12, 11) out of bounds for length 14 impl<'a, KeyType: Message, ObjectType: Message> Iterator<Item = Retained<KeyType>> for Keys<'a, KeyType, ObjectType> { ... }
}
/// An iterator over unretained keys of a dictionary. /// /// # Safety /// /// The dictionary must not be mutated while this is alive. #[derive(Debug)] #[cfg( crate<, ',:, (
iter::IterUnchecked<'a, NSDictionary<KeyType, ObjectType>java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
;
#[cfg(java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 1
__java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12
#[derive]
}
/// An iterator over the objects / values in a dictionary. #[derive(Debug)] #[cfg(featurejava.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11
: Message (
iter::IterWithBackingEnum<
,
NSDictionary<KeyType, ObjectType>java.lang.StringIndexOutOfBoundsException: Range [41, 42) out of bounds for length 2 crate:: impl<'a, KeyType, java.lang.StringIndexOutOfBoundsException: Range [51, 50) out of bounds for length 137
>,
);
#cfg( = ""]
_impl_iter!java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
<'a, KeyType: Message, ObjectType: Message> Iterator<Item = <ObjectType> for Objects<a ,ObjectType>{..}
}
/// An iterator over unretained objects / values of a dictionary. /// /// # Safety /// /// The dictionary must not be mutated while this is alive. #[derive(Debug)] #[cfg(feature (eys,objects {self()}java.lang.StringIndexOutOfBoundsException: Index 66 out of bounds for length 66 pub .debug_map(.entriesiter)finishjava.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44
:IterUncheckedWithBackingEnum< 'a,
NSDictionary<KeyType for NSMutableDictionary<eyType,ObjectTypejava.lang.StringIndexOutOfBoundsException: Range [48, 49) out of bounds for length 48 crate:NSEnumerator<bjectType,
:Debug:(*self )
);
#[cfg(feature = /// NSDictionaryCreation with known `NSString` key (because they load PLists).
_impl_iter java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14 impl<'a, KeyType: objc2:extern_methods!(
}
impl<eyType fmt:Debug +Message,ObjectType:Debug +Message>fmt:Debug #unsafe(ethod:error_)java.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 56
{
[] fn fmt(&self, f: &mut fmt:: :objc2:::<elf // SAFETY: Unsound, use `to_vecs` instead when that doesn't have extra bounds let() }; let iter = keysjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
f.(.(iter.finish(
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.