Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add msg_send_id! #120

Merged
merged 22 commits into from
Jun 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
7c26f19
Add msg_send_id to help with following memory management rules
madsmtm Jun 14, 2022
b4d4a77
Use msg_send_id everywhere
madsmtm Jun 14, 2022
c93b549
Disambiguate trait in msg_send_id
madsmtm Apr 3, 2022
c035c1d
Fix method family comparison in msg_send_id
madsmtm Jun 14, 2022
c9198d6
Add assembly tests for msg_send_id
madsmtm Jun 14, 2022
c3b047c
Remove extra branch between `msg_send_id!` alloc + init calls
madsmtm Jun 14, 2022
8f8b0e9
Add UI tests for msg_send_id!
madsmtm Jun 15, 2022
4252102
Disallow `retain`, `release` and `autorelease` in msg_send_id!
madsmtm Jun 15, 2022
4177dff
Allow msg_send_id![obj, init] to non-option wrapped Id
madsmtm Jun 15, 2022
b79f3cf
Special-case `msg_send_id[cls, new]` methods to only accept &Class
madsmtm Jun 15, 2022
d635b89
Fix UI compilation regression in msg_send_id![obj, init]
madsmtm Jun 15, 2022
aed5cdd
Improve msg_send_id! macro diagnostics a bit more
madsmtm Jun 15, 2022
f1ca00a
Test reference-counting properties of msg_send_id!
madsmtm Jun 15, 2022
67633bb
Don't leak macro implementation details in `msg_send_id!` docs
madsmtm Jun 15, 2022
e93af98
Rename internal macro helpers so their names are strictly more correct
madsmtm Jun 15, 2022
cd8bde5
Rewrite objc2 crate introductory text to further mention msg_send_id!
madsmtm Jun 15, 2022
ea7bc97
Rewrite msg_send! and msg_send_bool! docs
madsmtm Jun 15, 2022
4639e38
Document msg_send_id!
madsmtm Jun 15, 2022
f837735
Add changelog entry
madsmtm Jun 15, 2022
3f1f138
Small documentation fixes
madsmtm Jun 15, 2022
0e92a0a
Fix cargo +nightly doc
madsmtm Jun 15, 2022
726c660
Revert "Allow msg_send_id![obj, init] to non-option wrapped Id"
madsmtm Jun 15, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions objc2-foundation/examples/class_with_lifetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::sync::Once;
use objc2::declare::ClassBuilder;
use objc2::rc::{Id, Owned, Shared};
use objc2::runtime::{Class, Object, Sel};
use objc2::{msg_send, sel};
use objc2::{msg_send, msg_send_id, sel};
use objc2::{Encoding, Message, RefEncode};
use objc2_foundation::NSObject;

Expand All @@ -28,9 +28,8 @@ static MYOBJECT_REGISTER_CLASS: Once = Once::new();
impl<'a> MyObject<'a> {
fn new(number_ptr: &'a mut u8) -> Id<Self, Owned> {
unsafe {
let obj: *mut Self = msg_send![Self::class(), alloc];
let obj: *mut Self = msg_send![obj, initWithPtr: number_ptr];
Id::new(obj).unwrap()
let obj = msg_send_id![Self::class(), alloc];
msg_send_id![obj, initWithPtr: number_ptr].unwrap()
}
}

Expand Down
4 changes: 2 additions & 2 deletions objc2-foundation/examples/custom_class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::sync::Once;
use objc2::declare::ClassBuilder;
use objc2::rc::{Id, Owned};
use objc2::runtime::{Class, Object, Sel};
use objc2::{msg_send, sel};
use objc2::{msg_send, msg_send_id, sel};
use objc2::{Encoding, Message, RefEncode};
use objc2_foundation::NSObject;

Expand All @@ -25,7 +25,7 @@ static MYOBJECT_REGISTER_CLASS: Once = Once::new();
impl MYObject {
fn new() -> Id<Self, Owned> {
let cls = Self::class();
unsafe { Id::new(msg_send![cls, new]).unwrap() }
unsafe { msg_send_id![cls, new].unwrap() }
}

fn number(&self) -> u32 {
Expand Down
16 changes: 7 additions & 9 deletions objc2-foundation/src/attributed_string.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use objc2::msg_send;
use objc2::rc::{DefaultId, Id, Shared};
use objc2::runtime::Object;
use objc2::{msg_send, msg_send_id};

use crate::{
NSCopying, NSDictionary, NSMutableAttributedString, NSMutableCopying, NSObject, NSString,
Expand Down Expand Up @@ -47,28 +47,26 @@ impl NSAttributedString {
attributes: &NSDictionary<NSAttributedStringKey, Object>,
) -> Id<Self, Shared> {
unsafe {
let obj: *mut Self = msg_send![Self::class(), alloc];
let obj: *mut Self = msg_send![obj, initWithString: string, attributes: attributes];
Id::new(obj).unwrap()
let obj = msg_send_id![Self::class(), alloc];
msg_send_id![obj, initWithString: string, attributes: attributes].unwrap()
}
}

/// Creates a new attributed string without any attributes.
#[doc(alias = "initWithString:")]
pub fn from_nsstring(string: &NSString) -> Id<Self, Shared> {
unsafe {
let obj: *mut Self = msg_send![Self::class(), alloc];
let obj: *mut Self = msg_send![obj, initWithString: string];
Id::new(obj).unwrap()
let obj = msg_send_id![Self::class(), alloc];
msg_send_id![obj, initWithString: string].unwrap()
}
}
}

/// Querying.
impl NSAttributedString {
// TODO: Lifetimes?
pub fn string(&self) -> &NSString {
unsafe { msg_send![self, string] }
pub fn string(&self) -> Id<NSString, Shared> {
unsafe { msg_send_id![self, string].unwrap() }
}

/// Alias for `self.string().len_utf16()`.
Expand Down
12 changes: 3 additions & 9 deletions objc2-foundation/src/copying.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use objc2::rc::{Id, Owned, Ownership};
use objc2::{msg_send, Message};
use objc2::{msg_send_id, Message};

pub unsafe trait NSCopying: Message {
/// Indicates whether the type is mutable or immutable.
Expand Down Expand Up @@ -31,10 +31,7 @@ pub unsafe trait NSCopying: Message {
type Output: Message;

fn copy(&self) -> Id<Self::Output, Self::Ownership> {
unsafe {
let obj: *mut Self::Output = msg_send![self, copy];
Id::new(obj).unwrap()
}
unsafe { msg_send_id![self, copy].unwrap() }
}
}

Expand All @@ -46,9 +43,6 @@ pub unsafe trait NSMutableCopying: Message {
type Output: Message;

fn mutable_copy(&self) -> Id<Self::Output, Owned> {
unsafe {
let obj: *mut Self::Output = msg_send![self, mutableCopy];
Id::new(obj).unwrap()
}
unsafe { msg_send_id![self, mutableCopy].unwrap() }
}
}
12 changes: 5 additions & 7 deletions objc2-foundation/src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ use core::ops::{Index, IndexMut, Range};
use core::slice::{self, SliceIndex};
use std::io;

use objc2::msg_send;
use objc2::rc::{DefaultId, Id, Owned, Shared};
use objc2::runtime::{Class, Object};
use objc2::{msg_send, msg_send_id};

use super::{NSCopying, NSMutableCopying, NSObject, NSRange};

Expand Down Expand Up @@ -147,18 +147,16 @@ impl NSMutableData {
pub fn from_data(data: &NSData) -> Id<Self, Owned> {
// Not provided on NSData, one should just use NSData::copy or similar
unsafe {
let obj: *mut Self = msg_send![Self::class(), alloc];
let obj: *mut Self = msg_send![obj, initWithData: data];
Id::new(obj).unwrap()
let obj = msg_send_id![Self::class(), alloc];
msg_send_id![obj, initWithData: data].unwrap()
}
}

#[doc(alias = "initWithCapacity:")]
pub fn with_capacity(capacity: usize) -> Id<Self, Owned> {
unsafe {
let obj: *mut Self = msg_send![Self::class(), alloc];
let obj: *mut Self = msg_send![obj, initWithCapacity: capacity];
Id::new(obj).unwrap()
let obj = msg_send_id![Self::class(), alloc];
msg_send_id![obj, initWithCapacity: capacity].unwrap()
}
}
}
Expand Down
22 changes: 8 additions & 14 deletions objc2-foundation/src/dictionary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use core::ops::Index;
use core::ptr;

use objc2::rc::{DefaultId, Id, Owned, Shared, SliceId};
use objc2::{msg_send, Message};
use objc2::{msg_send, msg_send_id, Message};

use super::{NSArray, NSCopying, NSEnumerator, NSFastEnumeration, NSObject};

Expand Down Expand Up @@ -101,10 +101,7 @@ impl<K: Message, V: Message> NSDictionary<K, V> {
}

pub fn keys_array(&self) -> Id<NSArray<K, Shared>, Shared> {
unsafe {
let keys = msg_send![self, allKeys];
Id::retain_autoreleased(keys).unwrap()
}
unsafe { msg_send_id![self, allKeys] }.unwrap()
}

pub fn from_keys_and_objects<T>(keys: &[&T], vals: Vec<Id<V, Owned>>) -> Id<Self, Shared>
Expand All @@ -115,23 +112,20 @@ impl<K: Message, V: Message> NSDictionary<K, V> {

let cls = Self::class();
let count = min(keys.len(), vals.len());
let obj: *mut Self = unsafe { msg_send![cls, alloc] };
let obj: *mut Self = unsafe {
msg_send![
let obj = unsafe { msg_send_id![cls, alloc] };
unsafe {
msg_send_id![
obj,
initWithObjects: vals.as_ptr(),
forKeys: keys.as_ptr(),
count: count,
]
};
unsafe { Id::new(obj).unwrap() }
}
.unwrap()
}

pub fn into_values_array(dict: Id<Self, Owned>) -> Id<NSArray<V, Owned>, Shared> {
unsafe {
let vals = msg_send![&dict, allValues];
Id::retain_autoreleased(vals).unwrap()
}
unsafe { msg_send_id![&dict, allValues] }.unwrap()
}
}

Expand Down
2 changes: 1 addition & 1 deletion objc2-foundation/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ macro_rules! unsafe_def_fn {
$(#[$m])*
$v fn new() -> Id<Self, $o> {
let cls = Self::class();
unsafe { Id::new(msg_send![cls, new]).unwrap() }
unsafe { ::objc2::msg_send_id![cls, new].unwrap() }
}
};
}
12 changes: 5 additions & 7 deletions objc2-foundation/src/mutable_attributed_string.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use objc2::msg_send;
use objc2::rc::{DefaultId, Id, Owned, Shared};
use objc2::{msg_send, msg_send_id};

use crate::{NSAttributedString, NSCopying, NSMutableCopying, NSObject, NSString};

Expand All @@ -26,18 +26,16 @@ impl NSMutableAttributedString {
#[doc(alias = "initWithString:")]
pub fn from_nsstring(string: &NSString) -> Id<Self, Owned> {
unsafe {
let obj: *mut Self = msg_send![Self::class(), alloc];
let obj: *mut Self = msg_send![obj, initWithString: string];
Id::new(obj).unwrap()
let obj = msg_send_id![Self::class(), alloc];
msg_send_id![obj, initWithString: string].unwrap()
}
}

#[doc(alias = "initWithAttributedString:")]
pub fn from_attributed_nsstring(attributed_string: &NSAttributedString) -> Id<Self, Owned> {
unsafe {
let obj: *mut Self = msg_send![Self::class(), alloc];
let obj: *mut Self = msg_send![obj, initWithAttributedString: attributed_string];
Id::new(obj).unwrap()
let obj = msg_send_id![Self::class(), alloc];
msg_send_id![obj, initWithAttributedString: attributed_string].unwrap()
}
}
}
Expand Down
12 changes: 5 additions & 7 deletions objc2-foundation/src/mutable_string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use core::fmt;
use core::ops::AddAssign;
use core::str;

use objc2::msg_send;
use objc2::rc::{DefaultId, Id, Owned, Shared};
use objc2::{msg_send, msg_send_id};

use crate::{NSCopying, NSMutableCopying, NSObject, NSString};

Expand Down Expand Up @@ -39,18 +39,16 @@ impl NSMutableString {
#[doc(alias = "initWithString:")]
pub fn from_nsstring(string: &NSString) -> Id<Self, Owned> {
unsafe {
let obj: *mut Self = msg_send![Self::class(), alloc];
let obj: *mut Self = msg_send![obj, initWithString: string];
Id::new(obj).unwrap()
let obj = msg_send_id![Self::class(), alloc];
msg_send_id![obj, initWithString: string].unwrap()
}
}

#[doc(alias = "initWithCapacity:")]
pub fn with_capacity(capacity: usize) -> Id<Self, Owned> {
unsafe {
let obj: *mut Self = msg_send![Self::class(), alloc];
let obj: *mut Self = msg_send![obj, initWithCapacity: capacity];
Id::new(obj).unwrap()
let obj = msg_send_id![Self::class(), alloc];
msg_send_id![obj, initWithCapacity: capacity].unwrap()
}
}
}
Expand Down
9 changes: 3 additions & 6 deletions objc2-foundation/src/object.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use objc2::rc::{DefaultId, Id, Owned, Shared};
use objc2::runtime::{Class, Object};
use objc2::{msg_send, msg_send_bool};
use objc2::{msg_send, msg_send_bool, msg_send_id};

use super::NSString;

Expand All @@ -21,11 +21,8 @@ impl NSObject {
}

pub fn description(&self) -> Id<NSString, Shared> {
unsafe {
let result: *mut NSString = msg_send![self, description];
// TODO: Verify that description always returns a non-null string
Id::retain_autoreleased(result).unwrap()
}
// TODO: Verify that description always returns a non-null string
unsafe { msg_send_id![self, description].unwrap() }
}

pub fn is_kind_of(&self, cls: &Class) -> bool {
Expand Down
8 changes: 3 additions & 5 deletions objc2-foundation/src/process_info.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use objc2::msg_send;
use objc2::msg_send_id;
use objc2::rc::{Id, Shared};

use crate::{NSObject, NSString};
Expand All @@ -20,13 +20,11 @@ unsafe impl Sync for NSProcessInfo {}
impl NSProcessInfo {
pub fn process_info() -> Id<NSProcessInfo, Shared> {
// currentThread is @property(strong), what does that mean?
let obj: *mut Self = unsafe { msg_send![Self::class(), processInfo] };
// TODO: Always available?
unsafe { Id::retain_autoreleased(obj).unwrap() }
unsafe { msg_send_id![Self::class(), processInfo].unwrap() }
}

pub fn process_name(&self) -> Id<NSString, Shared> {
let obj: *mut NSString = unsafe { msg_send![Self::class(), processName] };
unsafe { Id::retain_autoreleased(obj).unwrap() }
unsafe { msg_send_id![self, processName].unwrap() }
}
}
16 changes: 6 additions & 10 deletions objc2-foundation/src/thread.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use objc2::rc::{Id, Shared};
use objc2::{msg_send, msg_send_bool};
use objc2::{msg_send, msg_send_bool, msg_send_id};

use crate::{NSObject, NSString};

Expand All @@ -15,20 +15,18 @@ unsafe impl Sync for NSThread {}

impl NSThread {
/// Returns the [`NSThread`] object representing the current thread.
pub fn current() -> Id<NSThread, Shared> {
pub fn current() -> Id<Self, Shared> {
// TODO: currentThread is @property(strong), what does that mean?
let obj: *mut Self = unsafe { msg_send![Self::class(), currentThread] };
// TODO: Always available?
unsafe { Id::retain_autoreleased(obj).unwrap() }
unsafe { msg_send_id![Self::class(), currentThread].unwrap() }
}

/// Returns the [`NSThread`] object representing the main thread.
pub fn main() -> Id<NSThread, Shared> {
// TODO: mainThread is @property(strong), what does that mean?
let obj: *mut Self = unsafe { msg_send![Self::class(), mainThread] };
// The main thread static may not have been initialized
// This can at least fail in GNUStep!
unsafe { Id::retain_autoreleased(obj).expect("Could not retrieve main thread.") }
unsafe { msg_send_id![Self::class(), mainThread] }.expect("Could not retrieve main thread.")
}

/// Returns `true` if the thread is the main thread.
Expand All @@ -38,13 +36,11 @@ impl NSThread {

/// The name of the thread.
pub fn name(&self) -> Option<Id<NSString, Shared>> {
let obj: *mut NSString = unsafe { msg_send![self, name] };
unsafe { Id::retain_autoreleased(obj) }
unsafe { msg_send_id![self, name] }
}

fn new() -> Id<Self, Shared> {
let obj: *mut Self = unsafe { msg_send![Self::class(), new] };
unsafe { Id::new(obj) }.unwrap()
unsafe { msg_send_id![Self::class(), new] }.unwrap()
}

fn start(&self) {
Expand Down
13 changes: 4 additions & 9 deletions objc2-foundation/src/uuid.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use objc2::rc::{Id, Shared};
use objc2::{msg_send, Encode, Encoding, RefEncode};
use objc2::{msg_send, msg_send_id, Encode, Encoding, RefEncode};

use super::{NSCopying, NSObject};

Expand Down Expand Up @@ -32,19 +32,14 @@ impl NSUUID {
// TODO: `nil` method?

pub fn new_v4() -> Id<Self, Shared> {
unsafe {
let obj: *mut Self = msg_send![Self::class(), alloc];
let obj: *mut Self = msg_send![obj, init];
Id::new(obj).unwrap()
}
unsafe { msg_send_id![Self::class(), new].unwrap() }
}

pub fn from_bytes(bytes: [u8; 16]) -> Id<Self, Shared> {
let bytes = UuidBytes(bytes);
unsafe {
let obj: *mut Self = msg_send![Self::class(), alloc];
let obj: *mut Self = msg_send![obj, initWithUUIDBytes: &bytes];
Id::new(obj).unwrap()
let obj = msg_send_id![Self::class(), alloc];
msg_send_id![obj, initWithUUIDBytes: &bytes].unwrap()
}
}

Expand Down
Loading