Мы разрабатываем приложение для обмена сообщениями и используем представление коллекции, которое содержит несколько типов ячеек.Ячейки имеют разные типы с динамическими размерами, одна из ячеек должна отображать стилизованный текст с многоцветными цветами и форматами, полученными от веб-сервера.Ячейка показывает это правильно при первом просмотре, но после прокрутки происходит сбой приложения при повторном рендеринге HTML с ошибкой:
Получено необработанное исключение ObjectiveC: NSRangeException
Мы реализовали наше представление коллекциина основе этой ссылки UICollectionView вставляет ячейки выше поддерживающей позиции (например, Messages.app)
Ниже приведен код:
Мы попытались добавить NSAttribute
s, вычисленные ккэш, но мы не можем получить их обратно как NSAttribute
s, поскольку они сохраняются в виде строк.
ChatCollectionViewSource.cs
[Export("collectionView:layout:sizeForItemAtIndexPath:"), CompilerGenerated]
public virtual CGSize GetSizeForItem(UICollectionView collectionView, UICollectionViewLayout layout, NSIndexPath indexPath)
{
var msg = chatMessages[indexPath.Row];
var estimatedFrame = new CGRect(0, 0, 220, 1000);
if(msg.Message.IsHtml()){
var ss = NSString ss = new NSString(msg.Message);
var htmlAttributes = TextHelper.GetHtmlNSAttributes(ss);
var estimatedFrame = TextHelper.GetEstimatedCGRectHtml(htmlAttributes);
return new CGSize(this.view.Frame.Width, estimatedFrame.Height + 24);
}
else {
// return cgsize of nonhtml text cell
}
}
public override UICollectionViewCell GetCell(UICollectionView collectionView, NSIndexPath indexPath)
{
var msg = chatMessages[indexPath.Row];
var textCell = collectionView.DequeueReusableCell("message_cell_identifier", indexPath) as MessageCell;
textCell.Layer.ShouldRasterize = true;
textCell.Layer.RasterizationScale = UIScreen.MainScreen.Scale;
var estimatedFrame = new CGRect(0, 0, 220, 1000);
if (msg.Message.IsHTML()) // html
{
NSString ss = new NSString(msg.Message);
NSAttributedString NSAttributes = null;
NSAttributes = TextHelper.GetHtmlNSAttributes(ss);
textCell.SetHTML(NSAttributes, msg.Date, msg.Id.ToString());
textCell.NSAttributedString = NSAttributes;
}
else
{
textCell.SetText(msg, msg.Date);
estimatedFrame = TextHelper.GetEstimatedCGRect(msg.Message); // get estimated frame
}
textCell.SetFrame(estimatedFrame, chatMessages[indexPath.Row].IsSend, this.view, msg);
return textCell;
}
MessageCell.cs
public void SetHTML(NSAttributedString NSAttributes, DateTime dateTime, string Id = null)
{
//ChatTextView.TextStorage.BeginEditing();
try
{
ChatTextView.TextColor = null;
if (NSAttributes != null)
{
DispatchQueue.MainQueue.DispatchAsync(() =>
{
ChatTextView.AttributedText = new NSMutableAttributedString(NSAttributes);
});
}
}
catch (Exception exception)
{
Debug.WriteLine(exception);
}}
TextHelper.cs
public static NSAttributedString GetHtmlNSAttributes(NSString HTMLtext)
{
var HTMLStyle = "<style>.body{font-family: '-apple-system', 'GothamMedium'; font-size:13; color:rgb(179, 178, 178);}</style>";
var text = HTMLStyle + "<div class='body'>" + HTMLtext + "</div>";
var ns = (NSString)text;
var myHtmlData = ns.Encode(NSStringEncoding.Unicode);
var options = new NSAttributedStringDocumentAttributes
{
DocumentType = NSDocumentType.HTML
};
NSError error = new NSError();
error = null;
NSDictionary dict = new NSDictionary();
dict = null;
try
{
var attrString = new NSAttributedString(myHtmlData, options, out dict, ref error);
return attrString;
}
catch (Exception ex)
{
Console.WriteLine(myHtmlData);
Console.WriteLine(ex.Message);
Console.WriteLine(options);
return null;
//throw ex;
}
}
Это на самом деле прекрасно работает
Мы пытаемся добавить функцию: Получить последние 50 сообщений (Бесконечная прокрутка) Когда пользователь прокручивает вверх список
ChatViewController.cs
#region scrolled to top observer
scrolledToTopObs = NSNotificationCenter.DefaultCenter.AddObserver((NSString)"scrolled_to_top",
async (notification) =>
{
var moreMessages = await Static.DB.getChatsAsync(this.CaseId, this.UserType, ++page);
if (moreMessages.Count == 0)
return;
list.InsertRange(0, moreMessages);
Debug.WriteLine("items count in list: " + list.Count);
// https://stackoverflow.com/questions/25548257/uicollectionview-insert-cells-above-maintaining-position-like-messages-app
NSIndexPath[] insertedPaths = new NSIndexPath[moreMessages.Count];
for (int i = 0; i < insertedPaths.Length; i++)
insertedPaths[i] = NSIndexPath.FromItemSection(i, 0);
DispatchQueue.MainQueue.DispatchAsync(() =>
{
var bottomOffset = ChatCollectionView.ContentSize.Height - ChatCollectionView.ContentOffset.Y;
CATransaction.Begin();
CATransaction.DisableActions = true;
ChatCollectionView.PerformBatchUpdates(() =>
{
ChatCollectionView.InsertItems(insertedPaths);
},
(finished) =>
{
ChatCollectionView.SetContentOffset(new CGPoint(0, ChatCollectionView.ContentSize.Height - bottomOffset), false);
CATransaction.Commit();
});
});
});
Приложение вылетает после DispatchQueue.MainQueue.DispatchAsync()
с этим отчетом о сбое:
2019-05-10 12: 10: 38.152 MyApp [1890: 923892] Xamarin.iOS: получено необработанное исключение ObjectiveC: NSRangeException * - [__ NSArrayM objectAtIndexedSubscript:]: индекс 16 за пределами [0 .. 15] 2019-05-10 12: 10: 38.156 MyApp [1890: 923892]....................... HTMLString типа NSAttributedString имеет значение null 2019-05-10 12: 10: 38.163 MyApp [1890: 923892] Сгенерировано исключение Objective C.Имя: NSRangeException Причина: * - [__ NSArrayM objectAtIndexedSubscript:]: индекс 16 за пределами [0 .. 15] Собственная трассировка стека: 0
CoreFoundation 0x00000001bb829ebc + 252 1 libobjc.A.dylib 0x00000001bajf_f_99* тысячу сорок-шесть * 0x00000001bb7a1384 _CFArgv + 0 3 CoreFoundation * 1 047 * 0x00000001bb724b78 + 0 4 UIKitCore * тысяча сорок-восемь * 0x00000001e82d4f5c + +1836 5 UIKitCore
0x00000001e82d69dc + 260 6 UIKitCore
0x00000001e82d0d48 + 44 7 UIKitCore
0x00000001e82b3d50 + +1648 8 UIKitCore *тысяча пятьдесят-дв * 0x00000001e82b3580 + 92 9 Фонд * тысяча пятьдесят-три * 0x00000001bc2c9420 __NSFireDelayedPerform + 404 10 CoreFoundation * тысяча пятьдесят четыре * 0x00000001bb7ba718 + 28 11 CoreFoundation
0x00000001bb7ba448 + 864 12 CoreFoundation
0x00000001bb7b9c7c + 248 13 CoreFoundation * тысяча пятьдесят-семь * 0x00000001bb7b4b58 + 1880 14 CoreFoundation * 1 058* 0x00000001bb7b40e0 CFRunLoopRunSpecific + 436 15 UIFoundation
0x00000001c5e42368 + 1728 16 UIFoundation
0x00000001c5e4533c + 28 17 UIFoundatioп * +1061 * 0x00000001c5e923ec _NSReadAttributedStringFromURLOrData + 8120 18 UIFoundation 0x00000001c5e45278 + 136 19 MyApp 0x000000010318b498 MyApp + 5911704 20 MyApp 0x0000000103143104 MyApp + 5615876 21 MyApp * тысяча шестьдесят-две * 0x000000010314329c MyApp + 5616284 22 MyApp
0x0000000102ca95f4 MyApp + 792052 23 MyApp
0x0000000102c7594c MyApp+ 579916 24 MyApp
0x000000010305b598 MyApp + 4666776 25 Моно * +1066 * 0x0000000105a38f08 mono_get_runtime_build_info + тысячу триста тридцать-две 26 Моно
0x0000000105add8a4 mono_runtime_invoke_checked + 152 27 Моно
0x0000000105ae1214 mono_runtime_invoke + 160 28 MyApp * 1 069 * 0x0000000102c40e98 MyApp + 364184 29 MyApp
0x0000000102c40af0 MyApp + 363248 30 UIKitCore
0x00000001e82d53ac + 2940 31 UIKitCore * 1 072 * 0x00000001e82d69dc + 260 32 UIKitCore * тысяча семьдесят-три * 0x00000001e82d0830 + 224 33 UIKitCore
0x00000001e82c9054 + 228 34 UIKitCore * тысяча семьдесят пять * 0x00000001e82ac2d4 + 10232 35 UIKitCore
0x00000001e82b3f90 + 92 36 UIKitCore
0x00000001e82b42c8 + 388 37 UIKitCore
0x00000001e82b4124 + 96 38 UIKitCore
0x00000001e82b40a8 + 84 39 UIKitCore
0x00000001e82b3fe4 + 64 40 MyApp
0x00000001031868f8 MyApp + 5892344 41 MyApp
0x0000000103129e88 MyApp + 5512840 42 MyApp
0x0000000102cc1878 MyApp + 891000 43 MyApp
0x000000010315a830 MyApp + 5711920 44 MyApp
0x0000000103194a7c MyApp + 5950076 45 libdispatch.dylib
0x00000001bb262484 + 16 46 libdispatch.dylib
0x00000001bb20e9a4 + 1068 47 CoreFoundation
0x00000001bb7b9ce4 + 12 48 CoreFoundation
0x00000001bb7b4bac + 1964 49 CoreFoundation
0x00000001bb7b40e0 CFRunLoopRunSpecific + 436 2019-05-10 12: 10: 38.163
MyApp [1890: 923892] 50 графических сервисов
0x00000001bda2d584 GSEventRunModal + 100 51 UIKitCore
0x00000001e89c8c00 UIApplicationMain + 212 52 MyApp
0x00000001031914e4 MyApp + 5936356 53 MyApp
0x000000010312798c MyApp + 5503372 54 MyApp
0x000000010312794c MyApp + 5503308 55 MyApp
0x0000000102c591c0 MyApp + 463296 56 MyApp
0x000000010305b598 MyApp + 4666776 57 Mono
0x0000000105a38f08 mono_get_runtime_build_info + 1332 58 Mono
0x0000000105add8a4 mono_runtime_invoke_checked + 152 59 Mono
0x0000000105ae3b54 mono_runtime_exec_main_checked + 120 60 Mono
0x0000000105a16bfc mono_jit_exec + 316 61 MyApp
0x000000010548777c _Z9__isctypeim + 56712 62 MyApp
0x0000000102c590b8 MyApp + 463032 63 libdyld.dylib
0x00000001bb272bb4 + 4
2019-05-10 12: 10: 38.163 MyApp [1890: 923892]
Foundation.NSAttributedStringDocumentAttributes достиг вершины
Кол-во просмотров 12:10:38 Количество элементов в списке: 300 объектов [1890]:
Неверный или преждевременно освобожденный пул авто-релиза 0x1057f33c8.
Собственные отчеты о сбоях
Получил SIGABRT при выполнении собственного кода. Это обычно указывает на
фатальная ошибка в моно среде выполнения или в одной из собственных библиотек
по вашему заявлению.
Базовая отчетность об отказах
Память вокруг родного указателя инструкций ...
Собственная трассировка стека:
0x105a30fc8 -
/private/var/containers/Bundle/Application/20685366-DEC9-4CB0-BA4E-3B41F073FEBD/MyApp.app/Frameworks/Mono.framework/Mono
: mono_dump_native_crash_info 0x105a270c8 -
/private/var/containers/Bundle/Application/20685366-DEC9-4CB0-BA4E-3B41F073FEBD/MyApp.app/Frameworks/Mono.framework/Mono
: mono_handle_native_crash 0x1bb4359f0 -
/usr/lib/system/libsystem_platform.dylib: 0x1bb3b780c -
/usr/lib/system/libsystem_kernel.dylib: 0x1bb3b77a8 -
/usr/lib/system/libsystem_kernel.dylib: 0x1ba9f94c4 -
/usr/lib/libobjc.A.dylib: 0x1ba9f941c -
/usr/lib/libobjc.A.dylib