How to resolve unrecognized selector sent to class? - iphone

My Question is similar to This SO question, but with the main difference being that I'm using class methods. Some code:
OpenFeint+private.h
#interface OpenFeint (Private)
// ...
+ (void) createSharedInstance;
OpenFeint+private.mm
+ (void) createSharedInstance
{
//...
}
OpenFeint.mm
+ (void) initializeWithProductKey:(NSString*)productKey
andSecret:(NSString*)productSecret
andDisplayName:(NSString*)displayName
andSettings:(NSDictionary*)settings
andDelegates:(OFDelegatesContainer*)delegatesContainer
{
[OpenFeint createSharedInstance];
// ...
MyApp.mm:
// ...
#import "OpenFeint.h"
// ...
[OpenFeint initializeWithProductKey: OF_PRODUCT_KEY
andSecret: OF_PRODUCT_SECRET
andDisplayName: OF_DISPLAY_NAME
andSettings: openFeintSettings
andDelegates: [OFDelegatesContainer containerWithOpenFeintDelegate: self]];
And the error is:
2010-07-22 11:30:15.239 MyApp[20210:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[OpenFeint createSharedInstance]: unrecognized selector sent to class 0x1cdb1c'
*** Call stack at first throw:
(
0 CoreFoundation 0x02d6f919 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x02ebd5de objc_exception_throw + 47
2 CoreFoundation 0x02d714eb +[NSObject(NSObject) doesNotRecognizeSelector:] + 187
3 CoreFoundation 0x02ce1116 ___forwarding___ + 966
4 CoreFoundation 0x02ce0cd2 _CF_forwarding_prep_0 + 50
5 MyApp 0x0002844d +[OpenFeint initializeWithProductKey:andSecret:andDisplayName:andSettings:andDelegates:] + 48
// ...
Everything compiles & links just fine, but I'm getting this goofy error.
One last thing -- All the OpenFeint stuff is is a static library and, yes, it compiled & linked as well. This is my first static library so I'm likely just missing some important step. Any clues?
Thanks!

Hmmm, I seem to have found a workaround, but I'm not sure if it's a correct fix. I added the linker flag -all_load (in addition to -ObjC), and all seems to work, now.
Question revision/addition: is this a "legit" fix? Is there a better one?

OpenFeint+private is a category so if you don't import the OpenFeint+private.h file everywhere you call it, you will get the selector not recognized error every time you call it. It's as if you never defined the method at all.

Related

Xcode 13 beta 5 error: UIViewController is missing its initial trait collection populated during initialization

App was working fine until Xcode 13 beta 5 builds.
Suddenly get this error in this init line of code in our view controller:
init(dataProvider: DataProvider) {
self.dataProvider = dataProvider
super.init(style: .plain)
dataProvider.delegate = self
}
This code was working fine in Xcode 12 and with no changes it now breaks with:
'NSInternalInconsistencyException', reason: 'UIViewController is
missing its initial trait collection populated during initialization.
This is a serious bug, likely caused by accessing properties or
methods on the view controller before calling a UIViewController
initializer. View controller: <UITableViewController: 0x7f7fbd291bb0>'
I googled around and only found 1 obscure thread on the issue but it wasnt much help.
Sometimes putting a breakpoint and stepping in allows it to work without crashing so there seems to be some sort of layout race condition under the hood but I am struggling to debug. I tried putting a sleep in but that doesn't work.
Any and all advice on how to debug this is appreciated. Right now I am unable to get additional info in order to debug. If you know what might be causing this or where to look I would appreciate your input.
Here is the error stack trace:
*** First throw call stack:
(
0 CoreFoundation 0x00007fff203fc8a8 __exceptionPreprocess + 242
1 libobjc.A.dylib 0x00007fff2019ebe7 objc_exception_throw + 48
2 Foundation 0x00007fff207501c9 -[NSMutableDictionary(NSMutableDictionary) classForCoder] + 0
3 UIKitCore 0x00007fff248310ed UIViewControllerMissingInitialTraitCollection + 188
4 UIKitCore 0x00007fff24835616 -[UIViewController traitCollection] + 155
5 UIKitCore 0x00007fff24824392 -[UITableViewController dealloc] + 196
6 App Dev 0x000000010e4f5680 $s05AppLaB027MyViewController
C14paymentMethods13selectedIndex5offer8delegateACSaySo16AppPaymentMethodCG_SiAA5Offer_pAA08CheckoutcD8Delegate_pSgtcfc + 368
7 App Dev 0x000000010e4f5726 $s05AppLaB027MyViewController
C14paymentMethods13selectedIndex5offer8delegateACSaySo16AppPaymentMethodCG_SiAA5Offer_pAA08CheckoutcD8Delegate_pSgtcfcTo + 102
8 App Dev 0x000000010e289291 -[CartViewController showPaymentMethodPickerWithPaymentMethods:] + 385
9 App Dev 0x000000010e289055 __59-[CartViewController showPaymentMethodPickerOrEntryForm]_block_invoke + 245
10 App Dev 0x000000010e7075ae $sSo16AppServiceResultVSo7NSArrayCSgSo7NSErrorCSgIeyByyy_ABSaySo16AppPaymentMethodCGSgs5Error_pSgIegygg_TR + 222
11 App Dev 0x000000010e707246 $sSo17AppAccountServiceC05AppLaD0E19fetchPaymentMethods11forListType7refresh09preferredF6Method10completionSo17AppRequestReceipt_pSgAC0fmiJ0O_S2bySo16AppServiceResultV_SaySo010AppPaymentM0CGSgs5Error_pSgtcSgtFyAN_ArTtcfU_ + 630
12 App Dev 0x000000010e707333 $sSo17AppAccountServiceC05AppLaD0E19fetchPaymentMethods11forListType7refresh09preferredF6Method10completionSo17AppRequestReceipt_pSgAC0fmiJ0O_S2bySo16AppServiceResultV_SaySo010AppPaymentM0CGSgs5Error_pSgtcSgtFyAN_ArTtcfU_TA + 35
13 App Dev 0x000000010e580474 $sSo16AppServiceResultVSaySo16AppPaymentMethodCGSgs5Error_pSgIegygg_ABSo7NSArrayCSgSo7NSErrorCSgIeyByyy_TR + 212
14 App Dev 0x000000010e39bcad __79-[AppAccountV3DAO fetchPaymentMethodsRefresh:preferredPaymentMethod:withBlock:]_block_invoke + 45
15 libdispatch.dylib 0x0000000110c18a18 _dispatch_call_block_and_release + 12
16 libdispatch.dylib 0x0000000110c19bfc _dispatch_client_callout + 8
17 libdispatch.dylib 0x0000000110c28366 _dispatch_main_queue_callback_4CF + 1195
18 CoreFoundation 0x00007fff2036a555 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
19 CoreFoundation 0x00007fff20364db2 __CFRunLoopRun + 2772
20 CoreFoundation 0x00007fff20363dfb CFRunLoopRunSpecific + 567
21 GraphicsServices 0x00007fff2cbb5cd3 GSEventRunModal + 139
22 UIKitCore 0x00007fff24fee193 -[UIApplication _run] + 928
23 UIKitCore 0x00007fff24ff2bfb UIApplicationMain + 101
24 App Dev 0x000000010e267120 main + 96
25 dyld 0x0000000110654e1e start_sim + 10
26 ??? 0x0000000000000001 0x0 + 1
27 ??? 0x0000000000000001 0x0 + 1
)
After commenting out a lot of code, I started getting a new error:
fatal error: Use of unimplemented initializer ‘init(style:)’ for class ‘PaymentPickerViewController’
Looking into the behaviour some more, it seems we have an objc initialized extension. I believe in this Xcode 13, the objc code gets mangled and doesn't "see" the root call to the initializer.
Our original init code path was this:
#objc extension PaymentPickerViewController {
convenience init() {
dataProvider = DataProvider()
self.init(dataProvider: dataProvider)
}
}
init(dataProvider: DataProvider) {
self.dataProvider = dataProvider
super.init(style: .plain)
}
The fix was explicitly overriding the swift init we wanted to use from the super:
override init(style: UITableView.Style) {
super.init(style: .plain)
self.dataProvider = DataProvider()
}
This forces the objc to see the correct init and then it works.
I fear the original error that I posted is very misleading so hopefully this helps anyone who runs into this issue.
Short description: For objective-C based implementation, could convert the object methods to class methods.
The following error was being reported on xcode13 GM Seed. Error Log:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UIViewController is missing
its initial trait collection populated during initialization. This is
a serious bug, likely caused by accessing properties or methods on the
view controller before calling a UIViewController initializer. View
controller: <MyViewController: 0x7fa5ae2356c0>'
For the following init method:
- (instancetype)initWithModel:(MyModel *)myModel {
MyViewController *vc = [[UIStoryboard storyboardWithName:#"Main" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:#"MyViewController"];
vc.model = myModel;
return vc;
}
init is invoked in the following manner from another View Controller.
// Before - invoking object method -- Results in the error
MyViewController *viewController = [[MyViewController alloc] initWithModel:testModel];
// After - invoking Class method
MyViewController *viewController = [MyViewController initWithModel:testModel];
In order to resolve it, I converted the init method to a class method.
+ (instancetype)initWithModel:(MyModel *)myModel {
MyViewController *vc = [[UIStoryboard storyboardWithName:#"Main" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:#"MyViewController"];
vc.model = myModel;
return vc;
}

Error: avcodec_init();

I'll try to compile under Ubuntu 14.04.2 and I get the following error:
VideoPlayerPipHd.c: In static member function ‘static void reel::VideoPlayerPipHd::Create()’:
VideoPlayerPipHd.c:792:6: error: ‘avcodec_init’ was not declared in this scope
avcodec_init -> avcodec_register_all;
^
VideoPlayerPipHd.c:793:7: error: ‘av_open_input_file’ was not declared in this scope
av_open_input_file -> avformat_open_input;
^
The code is:
787 void VideoPlayerPipHd::Create()
788 {
789 if (!instance_)
790 {
791 instance_ = new VideoPlayerPipHd;
792 avcodec_init();
793 avcodec_register_all();
794 }
795 }
I tried several things but I am stuck. Could somebody help me please?
Thanks in advance
The answer is that the ffmpeg functions are deprecated. See the list here for example:
https://www.ffmpeg.org/doxygen/0.8/deprecated.html
For example change av_open_input_file to avformat_open_input.

FakeItEasy ReturnsLazily with out parameter

I'm new to using FakeItEasy and rather stuck at my first attempt. The interface i want to fake has a method like this:
byte[] ReadFileChunk(string path,int offset,int count,out long size);
I would like to see how the arguments are passed on, so I'm using ReturnsLazily. Here is my attempt:
long resSize;
A.CallTo(() => dataAttributesController
.ReadFileChunk(A<string>.Ignored, A<int>.Ignored, A<int>.Ignored, out resSize))
.ReturnsLazily((string path, int offset, int count) =>
{
return Encoding.UTF8.GetBytes("You requested: " + path + "(" + offset + "," + count + ")");
})
.AssignsOutAndRefParameters(123);
This compiles, but when ran it generates this exception:
The faked method has the signature (System.String, System.Int32, System.Int32, System.Int64&), but returns lazily was used with (System.String, System.Int32, System.Int32).
Which is correct, but i can't figure out how to add the out parameter. If I change the ReturnLazily part to this:
.ReturnsLazily((string path, int offset, int count, out long size) =>
{
size = 0;
return Encoding.UTF8.GetBytes("You requested: " + path + "(" + offset + "," + count + ")");
})
it will not compile, and I don't understand the errors:
error CS1593: Delegate 'System.Func<FakeItEasy.Core.IFakeObjectCall,byte[]>' does not take 4 arguments
error CS1661: Cannot convert lambda expression to delegate type 'System.Func<string,int,int,long,byte[]>' because the parameter types do not match the delegate parameter types
error CS1677: Parameter 4 should not be declared with the 'out' keyword
For a novice like me, this reads like it doesn't like 4 parameters nor understands what to do with 'out'. Can someone please explain me how I should be reading these errors? A working example would be very welcome as well :-)
Thanks a lot!
--- EDIT ---
This seems to work:
A.CallTo(() => dataAttributesController
.ReadFileChunk(A<string>.Ignored, A<int>.Ignored, A<int>.Ignored, out resSize))
.ReturnsLazily(x =>
Encoding.UTF8.GetBytes("You requested: " + x.Arguments.Get<string>(0) + "(" + x.Arguments.Get<int>(1) + "," + x.Arguments.Get<int>(2) + ")"))
.AssignsOutAndRefParameters((long)123);
A bit less readable then I was hoping for, is this anywhere near the intended use of ReturnsLazily?
Is that interface under your control?
byte[] ReadFileChunk(string path, int offset, int count, out long size);
if so: Isn't out long size just the same as the size of the returning byte[]?
In that case I would just remove the size parameter from the interface method and use the "nice-to-read" ReturnsLazily method as you intended first.
Update: the issue I mention below was fixed in FakeItEasy release 1.15, so update to the latest version and you shouldn't have to worry about the out/ref specifiers on the methods when using ReturnsLazily.
Sorry for the delay. I'm glad you found a solution that at least functions for you.
I agree that the syntax you landed on isn't the most readable, but it does appear to be the correct one. The "convenience" versions of ReturnsLazily won't work with out/ref parameters because the lambda can't take the out/ref modifiers.
It doesn't help you today, but I've created FakeItEasy issue 168 to deal with the problem. If you have additional opinions, please drop by and comment or something.

Application Crash on NSIndexPath use in iOS5

#define PROPERTY_SECTION 0
#define SUBTOTAL_ROW 0
UITableViewCell *subtotalCell = [self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForItem:SUBTOTAL_ROW inSection:PROPERTY_SECTION]];
When i debug it in ios 6 it working perfect, But in ios 5 app crashed with following reason"
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[NSIndexPath indexPathForItem:inSection:]: unrecognized selector sent to class 0x1d41f20'
*** First throw call stack:
(0x26b4022 0x2083cd6 0x26b5aad 0x261aed0 0x261acb2 0xc956a 0xc9d4a 0xca3e9 0x12af38f 0x12af5eb 0x12bdb2b 0x12af38f 0x12af5eb 0x12b04ed 0x121da0c 0x26b5e99 0x121e464 0x121e495 0x1222fc1 0x121d14b 0x16864ce 0x162bd61 0x16114d0 0x12ae5ab 0x4ab35 0x14ade29 0x14ad133 0x14ae3bf 0x14b0a21 0x14b097c 0x14a93d7 0x268899e 0x261f640 0x25eb4c6 0x25ead84 0x25eac9b 0x2d167d8 0x2d1688a 0x11e6626 0x248d 0x23b5)
terminate called throwing an exception(lldb)
+ (NSIndexPath *)indexPathForItem:(NSInteger)item inSection:(NSInteger)section; is a method only works in UICollectionView in iOS 6. You can't use it in UITableView in iOS 5.
you are probably looking for indexPathForRow:inSection:
Use
[NSIndexPath indexPathForRow:indexRow inSection:indexSection];
instead of
[NSIndexPath indexPathForItem:indexRow inSection:indexSection];
It must be a method that is added in iOS6, because it doesn't exist in the iOS5 documentation located here :
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSIndexPath_Class/Reference/Reference.html
Edit: This method is only for a collection view, not a UITableView. Collection views are not supported in iOS 5

Why is my UILabel not recognising "isEqualToString:"? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How can I check if a UILabel's value is more than 0 in an if statement?
Why is the following code not working?
if([Period2 isEqualToString:#"PSHEEC"])
{
NSLog(#"TEST");
}
I am getting this error:
2011-12-02 08:45:52.579 iDHSB[7605:707] -[UILabel isEqualToString:]:
unrecognized selector sent to instance 0x4884c50 2011-12-02
08:45:52.581 iDHSB[7605:707] * Terminating app due to uncaught
exception 'NSInvalidArgumentException', reason: '-[UILabel
isEqualToString:]: unrecognized selector sent to instance 0x4884c50'
* First throw call stack: (0x323e28bf 0x35cfa1e5 0x323e5acb 0x323e4945 0x3233f680 0x3152b191 0x9c905 0x316cf871 0x323e5814
0x323407e1 0x323403ff 0x34767e5b 0x323e4ab3 0x3233f680 0x323e5814
0x323407e1 0x33dcb43d 0x33dde8dd 0x323b6b03 0x323b62cf 0x323b5075
0x323384d5 0x3233839d 0x378b7439 0x315558e1 0x2d77 0x27c0) terminate
called throwing an exception[Switching to process 7171 thread 0x1c03]
(gdb)
The error you are getting is propably due to memory mamagement issues, the pointer of Period2 is not pointing to you string any more and is now pointing to some label. Make sure you have retained it correctly.
On an other note, variable, properties, methods should not start with a capital, and if you label is a properties you should use self.period2 .
if period2 is your label use...
[period2.text isEqualToString:#"PSHEEC"]
It may be helpful
NSString *str = label.text;
if([str isEqualToString:#"PSHEEC"])
{
NSLog(#"Equal");
}
else
{
NSLog(#"Not Equal");
}
What is Period2? You can't test equivalence that way. If you want to test string equivalence, you need to do something like the following:
(assuming Period2 is an NSString)
if ([Period2 isEqualToString:#"PSHEEC]) {
NSLog(#"They are equal.");
}