【簡潔明瞭に】
カスタムセグエを書きました。
-(void)perform {
UIView *preV = ((UIViewController *)self.sourceViewController).view;
UIView *newV = ((UIViewController *)self.destinationViewController).view;
[preV.window insertSubview:newV aboveSubview:preV];
newV.center = CGPointMake(preV.center.x + preV.frame.size.width, newV.center.y);
[UIView animateWithDuration:0.4
animations:^{
newV.center = CGPointMake(preV.center.x, newV.center.y);
preV.center = CGPointMake(0- preV.center.x, newV.center.y);}
completion:^(BOOL finished){ [preV removeFromSuperview]; }];
}
セグエがトリガーされた場合、例外はありません。ただし、割り当てを解除 destinationViewController
します。
別のセグエをトリガーするボタンdestinationViewController
がクリックされると、アプリがクラッシュします。
削除しようとし[preV removeFromSuperview]
ましたが、無駄でした。
[詳細]
私は最近 Object-C を使い始め、プッシュ セグエをシミュレートするカスタム セグエを作成しました。
初めてトリガーされたときは、すべて正常に動作します。
しかし、その後、どのセグエがトリガーされても、アプリがクラッシュし、EXC_BAD_ACCESS
エラーが発生します。
私の最初の推測では、これはメモリ管理に関係しているということです。そこにあるものは割り当てを解除する必要がありますが、それが何であるかわかりません。
私の 2 番目の推測は、これは と によって提供されるインフラストラクチャに関係しているということUIView
ですUIWindow
。繰り返しになりますが、私の知識と経験の不足により、本当の問題が何であるかを理解することはできません。
を使用してナビゲーション バーを非表示にすることで、実際には簡単なアプローチでプッシュ セグエを作成できることはrootviewcontroller
わかっています。コードの生地。
【アップデート】
Phillip Mills と Joachim Isaksson の提案に感謝します。いくつかの実験を行い、ブレークポイントと Zombie ツールを利用した後、
これは私が実現するものです:
カスタム セグエがボタンによってトリガーされた後、アプリは次のセグエもボタンによってトリガーされた場合にのみクラッシュします。を使用して次のセグエをトリガーし
viewDidAppear
ても、クラッシュは発生しません。クラッシュの背後にある主な理由:
Objective-C メッセージが割り当て解除されたオブジェクト (ゾンビ) に送信されました
[#、イベントタイプ、refCt、ライブラリ、発信者]
0 Malloc 1 UIKit -[UIClassSwapper initWithCoder:]
1 Retain 2 UIKit -[UIRuntimeConnection initWithCoder:]
2 Retain 3 UIKit -[UIRuntimeConnection initWithCoder:]
3 Retain 4 UIKit -[UIRuntimeConnection initWithCoder:]
4 Retain 5 UIKit -[UIRuntimeConnection initWithCoder:]
5 Retain 6 UIKit -[UIRuntimeConnection initWithCoder:]
6 Retain 7 UIKit -[UIRuntimeConnection initWithCoder:]
7 Retain 8 UIKit -[UIRuntimeConnection initWithCoder:]
8 Retain 9 UIKit UINibDecoderDecodeObjectForValue
9 Retain 10 UIKit UINibDecoderDecodeObjectForValue
10 Retain 11 UIKit -[UIStoryboardScene setSceneViewController:]
11 Retain 12 UIKit -[UINib instantiateWithOwner:options:]
12 Release 11 UIKit -[UINibDecoder finishDecoding]
13 Release 10 UIKit -[UINibDecoder finishDecoding]
14 Release 9 UIKit -[UIRuntimeConnection dealloc]
15 Release 8 UIKit -[UIRuntimeConnection dealloc]
16 Release 7 UIKit -[UIRuntimeConnection dealloc]
17 Release 6 UIKit -[UIRuntimeConnection dealloc]
18 Release 5 UIKit -[UINibDecoder finishDecoding]
19 Release 4 UIKit -[UIRuntimeConnection dealloc]
20 Release 3 UIKit -[UIRuntimeConnection dealloc]
21 Release 2 UIKit -[UIRuntimeConnection dealloc]
22 Retain 3 UIKit -[UIStoryboardSegue initWithIdentifier:source:destination:]
23 Retain 4 ProjectX -[pushlike perform]
24 Retain 5 UIKit -[UINib instantiateWithOwner:options:]
25 Retain 6 UIKit +[UIProxyObject addMappingFromIdentifier:toObject:forCoder:]
26 Retain 7 UIKit -[UIProxyObject initWithCoder:]
27 Retain 8 UIKit -[UIRuntimeConnection initWithCoder:]
28 Retain 9 UIKit UINibDecoderDecodeObjectForValue
29 Retain 10 UIKit UINibDecoderDecodeObjectForValue
30 Release 9 UIKit -[UINib instantiateWithOwner:options:]
31 Release 8 UIKit +[UIProxyObject removeMappingsForCoder:]
32 Release 7 UIKit -[UINibDecoder finishDecoding]
33 Release 6 UIKit -[UIRuntimeConnection dealloc]
34 Release 5 UIKit -[UINibDecoder finishDecoding]
35 Release 4 UIKit -[UINibDecoder finishDecoding]
36 Release 3 ProjectX -[pushlike perform]
37 Retain 4 libsystem_sim_blocks.dylib _Block_object_assign
38 Retain 5 UIKit -[UIApplication _addAfterCACommitBlockForViewController:]
39 Release 4 UIKit -[UIStoryboardSegue dealloc]
40 Release 3 UIKit _UIApplicationHandleEvent
41 Release 2 UIKit -[UIStoryboardScene dealloc]
42 Retain 3 UIKit _applyBlockToCFArrayCopiedToStack
43 Release 2 UIKit _applyBlockToCFArrayCopiedToStack
44 Release 1 UIKit __destroy_helper_block_739
45 Release 0 UIKit _applyBlockToCFArrayCopiedToStack
46 Zombie -1 UIKit -[UIApplication sendAction:to:from:forEvent:]
つまり、(私が間違っていなければ)
destinationViewController
カスタム セグエは、別のセグエをトリガーするボタン ( の ) がクリックされた後にオブジェクト C メッセージが送信される、オブジェクトの割り当てを解除する何かをトリガーしました。
詳細
prepareForSegue
ビュー間でデータを渡す必要がないため、1 つも呼び出されていません。
私のセグエはすべて同じ方法でトリガーされます:
- (void)viewDidLoad
{
[super viewDidLoad];
CGRect buttonFrame = CGRectMake( 10, 40, 200, 50 );
UIButton *button = [[UIButton alloc] initWithFrame: buttonFrame];
[button setTitle: @"Go" forState: UIControlStateNormal];
[button addTarget:self action:@selector(nextView) forControlEvents:UIControlEventTouchUpInside];
[button setTitleColor: [UIColor blackColor] forState: UIControlStateNormal];
[self.view addSubview:button];
}
- (void)nextView{
[self performSegueWithIdentifier:@"push" sender:self];
}
私はARCを有効にしているので、自分で割り当て解除を実際に行っていません..
[更新 2]
ゾンビ化したオブジェクトがdestinationViewController
カスタムセグエです。
カスタム セグエを呼び出さなくremoveFromSuperview
ても、オブジェクトがゾンビに変わるのを止めることはできません。
作成したカスタム セグエの代わりに、通常のモデル セグエまたはプッシュ セグエ (rootViewController を使用) を使用する限り、ゾンビは発生せず、すべて正常に動作します。