use core::fmt; use core::hint::unreachable_unchecked; use core::panic::{RefUnwindSafe, UnwindSafe};
use objc2::exception::Exception; use objc2::rc::Retained; use objc2::runtime::{AnyObject, NSObject, NSObjectProtocol}; use objc2::{extern_methods, msg_send, sel, ClassType};
usecrate::{util, NSException};
// SAFETY: Exception objects are immutable data containers, and documented as // thread safe. unsafeimpl Sync for NSException {} unsafeimpl Send for NSException {}
impl UnwindSafe for NSException {} impl RefUnwindSafe for NSException {}
impl NSException { /// Create a new [`NSException`] object. /// /// Returns `None` if the exception couldn't be created (example: If the /// process is out of memory). #[cfg(all(feature = "NSObjCRuntime", feature = "NSString"))] #[cfg(feature = "NSDictionary")] pubfn new(
name: &crate::NSExceptionName,
reason: Option<&crate::NSString>,
user_info: Option<&crate::NSDictionary>,
) -> Option<Retained<Self>> { use objc2::AnyThread;
/// Raises the exception, causing program flow to jump to the local /// exception handler. /// /// This is equivalent to using `objc2::exception::throw`. pubfn raise(&self) -> ! { // SAFETY: `NSException` is immutable, so it is safe to give to // the place where `@catch` receives it. unsafe { self.raise_raw() }; // SAFETY: `raise` will throw an exception, or abort if something // unexpected happened. unsafe { unreachable_unchecked() }
}
/// Convert this into an [`Exception`] object. pubfn into_exception(this: Retained<Self>) -> Retained<Exception> { // SAFETY: Downcasting to "subclass" unsafe { Retained::cast_unchecked(this) }
}
fn is_nsexception(obj: &Exception) -> bool { if obj.class().responds_to(sel!(isKindOfClass:)) { // SAFETY: We only use `isKindOfClass:` on NSObject let obj: *const Exception = obj; let obj = unsafe { obj.cast::<NSObject>().as_ref().unwrap() };
obj.isKindOfClass(Self::class())
} else { false
}
}
/// Create this from an [`Exception`] object. /// /// This should be considered a hint; it may return `Err` in very, very /// few cases where the object is actually an instance of `NSException`. pubfn from_exception(obj: Retained<Exception>) -> Result<Retained<Self>, Retained<Exception>> { ifSelf::is_nsexception(&obj) { // SAFETY: Just checked the object is an NSException
Ok(unsafe { Retained::cast_unchecked::<Self>(obj) })
} else {
Err(obj)
}
}
}
impl fmt::Debug for NSException { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let obj: &AnyObject = self.as_ref();
write!(f, "{obj:?}")?;
write!(f, " '")?; let name: Retained<NSObject> = unsafe { msg_send![self, name] }; // SAFETY: `name` returns `NSExceptionName`, which is `NSString`. unsafe { util::display_string(&name, f)? };
write!(f, "'")?;
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.