Skip to content

Commit accb715

Browse files
authored
[Foundation] Improve NSArray.FromIntPtrs slightly. (#24501)
* Enable nullability. * Simplify code, with both reduced memory footprint, and faster execution speed. * Add tests. * Add xml docs. Contributes towards #17285.
1 parent ae6a664 commit accb715

File tree

3 files changed

+45
-12
lines changed

3 files changed

+45
-12
lines changed

src/Foundation/NSArray.cs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,7 @@ static public NSArray FromStrings (IReadOnlyList<string> items)
283283
}
284284
}
285285

286+
#nullable enable
286287
/// <summary>Create an <see cref="NSArray" /> from the specified pointers.</summary>
287288
/// <param name="items">Array of pointers (to <see cref="NSObject" /> instances).</param>
288289
/// <remarks>If the <paramref name="items" /> array is null, an <see cref="ArgumentNullException" /> is thrown.</remarks>
@@ -293,24 +294,25 @@ static internal NSArray FromIntPtrs (IntPtr [] items)
293294

294295
unsafe {
295296
fixed (IntPtr* valuesPtr = items)
296-
return Runtime.GetNSObject<NSArray> (NSArray.FromObjects ((IntPtr) valuesPtr, items.Length))!;
297+
return Runtime.GetNSObject<NSArray> (NSArray.FromObjects ((IntPtr) valuesPtr, items.Length)) ?? new NSArray ();
297298
}
298299
}
299300

300-
static public NSArray FromIntPtrs (NativeHandle [] vals)
301+
/// <summary>Create an <see cref="NSArray" /> from the specified pointers.</summary>
302+
/// <param name="vals">Array of pointers (to <see cref="NSObject" /> instances).</param>
303+
/// <remarks>If the <paramref name="vals" /> array is null, an <see cref="ArgumentNullException" /> is thrown.</remarks>
304+
public static NSArray FromIntPtrs (NativeHandle [] vals)
301305
{
302306
if (vals is null)
303-
throw new ArgumentNullException ("vals");
304-
int n = vals.Length;
305-
IntPtr buf = Marshal.AllocHGlobal (n * IntPtr.Size);
306-
for (int i = 0; i < n; i++)
307-
Marshal.WriteIntPtr (buf, i * IntPtr.Size, vals [i]);
308-
309-
NSArray arr = Runtime.GetNSObject<NSArray> (NSArray.FromObjects (buf, vals.Length));
307+
throw new ArgumentNullException (nameof (vals));
310308

311-
Marshal.FreeHGlobal (buf);
312-
return arr;
309+
unsafe {
310+
fixed (NativeHandle* valuesPtr = vals) {
311+
return Runtime.GetNSObject<NSArray> (NSArray.FromObjects ((IntPtr) valuesPtr, vals.Length)) ?? new NSArray ();
312+
}
313+
}
313314
}
315+
#nullable disable
314316

315317
internal static nuint GetCount (IntPtr handle)
316318
{

tests/cecil-tests/Documentation.KnownFailures.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11806,7 +11806,6 @@ M:Foundation.INSUrlSessionWebSocketDelegate.DidOpen(Foundation.NSUrlSession,Foun
1180611806
M:Foundation.INSXpcListenerDelegate.ShouldAcceptConnection(Foundation.NSXpcListener,Foundation.NSXpcConnection)
1180711807
M:Foundation.NSArray.ArrayFromHandle``1(ObjCRuntime.NativeHandle,System.Converter{ObjCRuntime.NativeHandle,``0},System.Boolean)
1180811808
M:Foundation.NSArray.EnumsFromHandle``1(ObjCRuntime.NativeHandle)
11809-
M:Foundation.NSArray.FromIntPtrs(ObjCRuntime.NativeHandle[])
1181011809
M:Foundation.NSArray.FromNSObjects``1(``0[][])
1181111810
M:Foundation.NSArray.FromNSObjects``1(``0[0:,0:])
1181211811
M:Foundation.NSArray.FromStrings(System.Collections.Generic.IReadOnlyList{System.String})

tests/monotouch-test/Foundation/NSArray1Test.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,38 @@ public void ToArray_T ()
125125
}
126126
}
127127

128+
[Test]
129+
public void FromIntPtrs_NativeHandle ()
130+
{
131+
var str1 = (NSString) "1";
132+
var str2 = (NSString) "2";
133+
var str3 = (NSString) "3";
134+
135+
var handles = new NativeHandle [] { str1.Handle, str2.Handle, str3.Handle };
136+
using (var arr = NSArray.FromIntPtrs (handles)) {
137+
Assert.AreEqual ((nuint) 3, arr.Count, "NSArray Count");
138+
Assert.AreEqual ("1", arr.GetItem<NSString> (0).ToString (), "NSArray item 0");
139+
Assert.AreEqual ("2", arr.GetItem<NSString> (1).ToString (), "NSArray item 1");
140+
Assert.AreEqual ("3", arr.GetItem<NSString> (2).ToString (), "NSArray item 2");
141+
}
142+
}
143+
144+
[Test]
145+
public void FromIntPtrs_NativeHandle_Null ()
146+
{
147+
NativeHandle []? handles = null;
148+
Assert.Throws<ArgumentNullException> (() => NSArray.FromIntPtrs (handles!), "Null array");
149+
}
150+
151+
[Test]
152+
public void FromIntPtrs_NativeHandle_Empty ()
153+
{
154+
var handles = new NativeHandle [0];
155+
using (var arr = NSArray.FromIntPtrs (handles)) {
156+
Assert.AreEqual ((nuint) 0, arr.Count, "NSArray Count");
157+
}
158+
}
159+
128160
#if false // https://github.com/dotnet/macios/issues/15577
129161
[Test]
130162
public void GetDifferenceFromArrayTest ()

0 commit comments

Comments
 (0)