I am trying to implement an event to command behavior(as demonstrated by Xamarin:https://github.com/xamarin/xamarin-forms-samples/tree/master/Behaviors/EventToCommandBehavior)
As soon as I try to add a TabbedPage.Behaviors section to my TabbedPage.Xaml the app will crash on launch in iOS with the following exception:
Foundation.MonoTouchException: Objective-C exception thrown. Name: NSInternalInconsistencyException Reason: Application windows are expected to have a root view controller at the end of application launch
Native stack trace:
0 CoreFoundation 0x000000010b48434b __exceptionPreprocess + 171
1 libobjc.A.dylib 0x0000000115be221e objc_exception_throw + 48
2 CoreFoundation 0x000000010b488442 +[NSException raise:format:arguments:] + 98
3 Foundation 0x000000010c065e4d -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 195
4 UIKit 0x000000010ecb0619 -[UIApplication _runWithMainScene:transitionContext:completion:] + 3827
5 UIKit 0x000000010ecacf69 -[UIApplication workspaceDidEndTransaction:] + 188
6 FrontBoardServices 0x000000011890b723 __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 24
7 FrontBoardServices 0x000000011890b59c -[FBSSerialQueue _performNext] + 189
8 FrontBoardServices 0x000000011890b925 -[FBSSerialQueue _performNextFromRunLoopSource] + 45
9 CoreFoundation 0x000000010b429311 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
10 CoreFoundation 0x000000010b40e59c __CFRunLoopDoSources0 + 556
11 CoreFoundation 0x000000010b40da86 __CFRunLoopRun + 918
12 CoreFoundation 0x000000010b40d494 CFRunLoopRunSpecific + 420
13 UIKit 0x000000010ecab7e6 -[UIApplication _run] + 434
14 UIKit 0x000000010ecb1964 UIApplicationMain + 159
15 ??? 0x000000012e4eb58c 0x0 + 5071877516
16 ??? 0x000000012e4eb1fd 0x0 + 5071876605
at at (wrapper managed-to-native) UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
at UIKit.UIApplication.Main (System.String[] args, System.IntPtr principal, System.IntPtr delegate) [0x00005] in /Users/builder/data/lanes/3969/44931ae8/source/xamarin-macios/src/UIKit/UIApplication.cs:79
at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x00038] in /Users/builder/data/lanes/3969/44931ae8/source/xamarin-macios/src/UIKit/UIApplication.cs:63
at TabDemo.iOS.Application.Main (System.String[] args) [0x00008] in /Users/Shared/git/Experiments/TabDemo/TabDemo.iOS/Main.cs:17
On Android the app simply hangs on launch and never displays the tabbed page.
MyTabbedPage.Xaml looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<TabbedPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
prism:ViewModelLocator.AutowireViewModel="True"
xmlns:local="clr-namespace:TabDemo.Views"
xmlns:behaviors="clr-namespace:TabDemo.Views.Behaviors"
x:Class="TabDemo.Views.MyTabbedPage">
<TabbedPage.Behaviors>
<behaviors:EventToCommandBehavior
EventName="CurrentPageChanged"
Command="{Binding OnCurrentPageChangedCommand}" />
</TabbedPage.Behaviors>
<NavigationPage
Title="Main">
<x:Arguments>
<local:MainPage />
</x:Arguments>
</NavigationPage>
<NavigationPage
Title="Second">
<x:Arguments>
<local:SecondPage />
</x:Arguments>
</NavigationPage>
</TabbedPage>
Wiring up the behavior in the code behind leads to the exact same problem. If I remove the behavior entry in the TabbedPage.Behaviors section the app runs fine on both platforms.
Can anyone shed some light on what I might be doing wrong?
I believe you might need to change the type that EventToCommandBehavior inherits from. Open the EventToCommandBehavior.cs file and change:
public class EventToCommandBehavior : BehaviorBase<View>
to:
public class EventToCommandBehavior : BehaviorBase<VisualElement>
You will also need to modify the signature of two methods:
protected override void OnAttachedTo (View bindable)
protected override void OnDetachingFrom (View bindable)
to:
protected override void OnAttachedTo(VisualElement bindable)
protected override void OnDetachingFrom(VisualElement bindable)
If you're following the straight up example for the EventToCommandBehavior, my guess would be that there is an exception being thrown because your command expects a different type than what is being passed in. Without seeing your project, or knowing what you're trying to accomplish, it's hard to give you a clearer direction.
You might try taking a look at this Gist that provides an example of how to add a behavior to a TabbedPage on CurrentPageChanged: https://gist.github.com/dansiegel/cdc81671f3610d8992d70c65c202f0a4
Related
In OCMockito, test doubles are implemented with NSProxy. A double standing in for an instance implements -respondsToSelector: as follows:
- (BOOL)respondsToSelector:(SEL)aSelector {
return [_mockedClass instancesRespondToSelector:aSelector];
}
But a double standing in for a class implements -respondsToSelector: like this:
- (BOOL)respondsToSelector:(SEL)aSelector {
return [_mockedClass respondsToSelector:aSelector];
}
This all works in the 32-bit runtime. For example, if _mockedClass is [NSString class], the proxy correctly answers that it responds to the selector +pathWithComponents:
But in the 64-bit runtime, it crashes:
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: EXC_I386_GPFLT
Application Specific Information:
objc[1868]: GC: forcing GC OFF because OBJC_DISABLE_GC is set
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 libobjc.A.dylib 0x00007fff95cbffc6 cache_getImp + 6
1 libobjc.A.dylib 0x00007fff95ccd1dc lookUpImpOrForward + 50
2 libobjc.A.dylib 0x00007fff95ccd198 lookUpImpOrNil + 20
3 libobjc.A.dylib 0x00007fff95cc218a class_respondsToSelector + 37
4 com.apple.CoreFoundation 0x00007fff91c131ad ___forwarding___ + 429
5 com.apple.CoreFoundation 0x00007fff91c12f78 _CF_forwarding_prep_0 + 120
6 org.mockito.OCMockitoTests 0x000000010451a55b -[StubClassTest testStubbedMethod_ShouldReturnGivenObject] + 107 (StubClassTest.m:48)
Note that it's calling class_respondsToSelector(…). I suspect that I'm being bitten by an optimization made to the runtime. What can I do to fix this?
it's a bit long answer, so bear with me. I ran a simple code just to verify the behavior:
Class mock = mockClass([NSProcessInfo class]);
[mock processInfo];
[verify(mock) processInfo];
Indeed It does crash with bad pointer exception. Replacing first line with
id mock = mockClass([NSProcessInfo class]);
works as expected. I figured that it might be worth to look at the code after ARC. Those snippets are a bit to long, so here are the gists: Class-based test, id-based test
As you can see, when you declare variable of type Class there is an extra release. My guess is that since classes are registered for the entire runtime duration (unless removed using runtime api) it's ok to have Class variable as __unsafe_unretained.
To summarize, you have two possible solutions:
#implementation StubClassTest
{
__strong Class mockClass;
}
or
#implementation StubClassTest
{
id mockClass;
}
seem to fix the issue for me.
Update
As a special case, if the object’s base type is Class (possibly protocol-qualified), the type is adjusted to have __unsafe_unretained qualification instead.
From http://clang.llvm.org/docs/AutomaticReferenceCounting.html#objects
My wire up looks like this.
return Wireup.Init()
.UsingRavenPersistence("RavenDB")
.ConsistentQueries()
.InitializeStorageEngine()
.UsingJsonSerialization()
.Build();
When I try to save an event, like this:
using (eventStore)
using (var stream = eventStore.CreateStream(myEvent.AggreagateId))
{
stream.Add(new EventMessage { Body = myEvent });
stream.CommitChanges(myEvent.Id);
}
It throws an EventStore.ConcurrencyException
I'm using eventstore 3.0 and RavenDB 2.0
What am I doing wrong?
Here is the stack trace:
EventStore.ConcurrencyException was unhandled by user code
HResult=-2146233088
Message=Exception of type 'EventStore.ConcurrencyException' was thrown.
Source=EventStore.Persistence.RavenPersistence
StackTrace:
at EventStore.Persistence.RavenPersistence.RavenPersistenceEngine.Commit(Commit attempt) in c:\Code\public\EventStore\src\proj\EventStore.Persistence.RavenPersistence\RavenPersistenceEngine.cs:line 135
at EventStore.OptimisticEventStore.Commit(Commit attempt) in c:\Code\public\EventStore\src\proj\EventStore.Core\OptimisticEventStore.cs:line 98
at EventStore.OptimisticEventStream.PersistChanges(Guid commitId) in c:\Code\public\EventStore\src\proj\EventStore.Core\OptimisticEventStream.cs:line 166
at EventStore.OptimisticEventStream.CommitChanges(Guid commitId) in c:\Code\public\EventStore\src\proj\EventStore.Core\OptimisticEventStream.cs:line 147
at TeamHabits.Web.Habit.CreateHabitModule.<>c__DisplayClass6.<.ctor>b__1(Object _) in c:\Users\Emil\Dropbox\Active projects\TeamHabits\Source\TeamHabits.Web\Habit\CreateHabitModule.cs:line 41
at Nancy.Routing.Route.Invoke(DynamicDictionary parameters)
at Nancy.Routing.DefaultRouteInvoker.Invoke(Route route, DynamicDictionary parameters, NancyContext context)
at Nancy.Routing.DefaultRequestDispatcher.Dispatch(NancyContext context)
InnerException:
I have a class called Node which contains a set of parameters and an NSMutableArray called subNodes. One process creates one Node object as a root of the tree and uses the subNodes arrays to create a large tree of Nodes. This entire tree should be passed to another process, so I set up an NSConnection:
Node *tree;
// ...create Node-Tree...
NSConnection *otherProcess = [NSConnection connectionWithRegisteredName:#"MyApp"
host:nil];
MyObj *remoteObj = (MyObj*) [[otherProcess rootProxy] retain];
[remoteObj setNodeTree:tree];
The communication itself works, the remote method 'setNodeTree', which expects the root-Node will be called. However, the transfer of the tree doesn't work. I had to implement a copyWithZone method for the Node class:
-(id)copyWithZone:(NSZone*)zone
{
Node *nodeCopy = [[[self class] allocWithZone:zone] init];
[nodeCopy setSize:[self size]];
[nodeCopy setSubnodes:[[self subnodes] copyWithZone:zone]];
return nodeCopy;
}
But the client terminates with the following exception:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException',
reason: '[NOTE: this exception originated in the server.]
Cannot create BOOL from object <Node: 0x10018f640> of class NSDistantObject'
*** Call stack at first throw:
(
0 CoreFoundation 0x00007fff81f687b4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x00007fff823a80f3 objc_exception_throw + 45
2 Foundation 0x00007fff8831e0c3 -[NSConnection sendInvocation:internal:] + 4304
3 CoreFoundation 0x00007fff81f3a98c ___forwarding___ + 860
4 CoreFoundation 0x00007fff81f36a68 _CF_forwarding_prep_0 + 232
5 MyProgram 0x00000001000015d5 main + 260
6 MyProgram 0x0000000100000fa8 start + 52
7 ??? 0x0000000000000002 0x0 + 2
)
terminate called after throwing an instance of 'NSException'
Any ideas what went wrong here? Apparently a BOOL variable is expected somewhere, but the Node doesn't contain any and there is no method used which expects or returns a BOOL.
Two alternatives are possible:
serialization and deserialization of whole tree,
shared memory between processes.
For performance and code readability, my preference goes to shared memory. A reference start is shmget(2) manual page.
Has anybody an idea in which case this can happen?
GDB output:
0 .. 8: kill, abort, objc_exception_throw etc.
9: 0x00007fff87ea21f4 in +[NSException raise:format:] ()
10: 0x00007fff8694e9e2 in -[NSBezierPath currentPoint] ()
11: 0x00007fff869e3b3b in __NSAppendBezierPathWithGlyphs ()
12: 0x00007fff869e5baf in -[NSBezierPath appendBezierPathWithGlyphs:count:inFont:]()
13: 0x00007fff869e2e2d in -[NSBezierPath appendBezierPathWithGlyph:inFont:] ()
objc_exception_throw is the function to throw an exception. There are two things to look at in this circumstance: The Console log, which will identify the exception itself, and the call stack leading to objc_exception_throw.
In this case, I can guess what the exception was from the call stack alone: currentPoint will throw if the path has no current point. This is backed up by the documentation for the appendBezierPathWithGlyphs:count:inFont: method (as well as for the method you're directly calling):
You must set the path's current point (using the moveToPoint: method or through the creation of a preceding line or curve segment) before you invoke this method.
(gdb) bt
#0 0x302ac924 in ___TERMINATING_DUE_TO_UNCAUGHT_EXCEPTION___ ()
#1 0x92077e3b in objc_exception_throw ()
#2 0x302d6ffb in -[NSObject doesNotRecognizeSelector:] ()
#3 0x3026e056 in ___forwarding___ ()
#4 0x3024a0a2 in __forwarding_prep_0___ ()
#5 0x00004ae9 in -[GameObject doesTouch:] (self=0xe893a0, _cmd=0x643ee, obj=0xe82e20) at /Users/aaa/Desktop/CPT/Game/Classes/GameObject.m:220
#6 0x00006e05 in -[StaticGrid checkTouchNearest:] (self=0xe82f20, _cmd=0x64ec3, obj=0xe893a0) at /Users/aaa/Desktop/CPT/Game/Classes/StaticGrid.m:62
#7 0x0000a393 in -[EAGLView touchesBegan:withEvent:] (self=0xe8dad0, _cmd=0x3199fa3c, touches=0x632c0b0, event=0xe14590) at /Users/aaa/Desktop/CPT/Game/Classes/EAGLView.m:459
#8 0x30910f33 in -[UIWindow _sendTouchesForEvent:] ()
#9 0x308faecb in -[UIApplication sendEvent:] ()
#10 0x309013e1 in _UIApplicationHandleEvent ()
#11 0x32046375 in PurpleEventCallback ()
#12 0x30245560 in CFRunLoopRunSpecific ()
#13 0x30244628 in CFRunLoopRunInMode ()
#14 0x32044c31 in GSEventRunModal ()
#15 0x32044cf6 in GSEventRun ()
#16 0x309021ee in UIApplicationMain ()
...
Currently I have a rare occuring error that I do not know the cause yet. I am not sure where to look at, so what I want to ask is what do the first five lines (#0 to #4) mean? I know that it claims that there are some errors, but what are those things like "___forwarding___"?
If you have some knowledge in this, please help. Thank you very much.
The forwarding stuff is used for uhm… forwarding messages. Each object can easily forward the messages it receives to some other objects, see the excellent tutorial by Scott Stevenson. When your GameObject receives a message it does not understand, it tries to forward it. If there is no forwarding implemented, the doesNotRecognizeSelector method is called and you get the exception.
Detailed description can be found in the Apple documentation for the NSObject class:
When an object is sent a message for
which it has no corresponding method,
the runtime system gives the receiver
an opportunity to delegate the message
to another receiver. It delegates the
message by creating an NSInvocation
object representing the message and
sending the receiver a
forwardInvocation: message containing
this NSInvocation object as the
argument. The receiver’s
forwardInvocation: method can then
choose to forward the message to
another object.
(…)
NSObject’s implementation of
forwardInvocation: simply invokes the
doesNotRecognizeSelector: method; it
doesn’t forward any messages. Thus, if
you choose not to implement
forwardInvocation:, sending
unrecognized messages to objects will
raise exceptions.
As for your error, it seems that the GameObject gets sent some message it does not understand. This can be a simple typo or something more subtle like memory management error, you’d have to give us more information.
First thing I would check is whether GameObject has a -doesTouch: or +doesTouch: method. I am not sure what __forwarding... is. What error message do you see in the console log?