2012-11-15 50 views
3

我認爲新符號是這樣的:someArray [5]爲什麼以及如何在objective-c中工作?

的someArray [5]變爲

的someArray [5]實際上會變成[objectAtIndexedSubscript的someArray:5]

然而,在NSArray.h和NSOrderedSet.h我看到這個:

- (id)objectAtIndexedSubscript:(NSUInteger)idx NS_AVAILABLE(10_8, 6_0); 

因此,objectAtIndexedSubscript只適用於IOS6。

我嘗試使這個簡單的代碼:

NSArray * someArray [email protected][@"hello",@"World",@"World"]; 
NSOrderedSet * someOS = [NSOrderedSet orderedSetWithArray:someArray]; 
PO(someArray); 
PO(someOS); 
PO(someArray[0]); 
PO(someOS[0]); //Exception thrown here 

在someOS代碼符號[0]

-[__NSOrderedSetI objectAtIndexedSubscript:]: unrecognized selector sent to instance 0x8b1fac0 
在BOTH NSArray的和NSOrderedSet

,有一個文本NS_AVAILABLE(10_8,6_0);

然而,它並沒有在NSArray上打破NSOrderedSet。爲什麼?

獎勵:我把它NSOrderedSet工作太與類別如何做(需要檢查它尚未定義)

+1

什麼是您的PO()?我沒有得到任何例外。 – sunkehappy

回答

3

我有更好的回答!

對於不支持-objectAtIndexedSubscript:的iOS版本,此代碼將動態地修補NSOrderedSet

#import <Foundation/Foundation.h> 
#import <objc/runtime.h> 

id PatchedObjectAtIndexedSubscript(id self_, SEL cmd_, NSUInteger index) 
{ 
    return [self_ objectAtIndex:index]; 
} 

void PatchedSetObjectAtIndexedSubscript(id self_, SEL cmd_, id object, NSUInteger index) 
{ 
    return [self_ replaceObjectAtIndex:index withObject:object]; 
} 

void SIPatchNSOrderedSet() 
{ 
    char types[6]; 

    if (!class_getInstanceMethod([NSOrderedSet class], @selector(objectAtIndexedSubscript:))) { 
     sprintf(types, "@@:%s", @encode(NSUInteger)); 
     class_addMethod([NSOrderedSet class], 
         @selector(objectAtIndexedSubscript:), 
         (IMP)PatchedObjectAtIndexedSubscript, 
         types); 
    } 

    if (!class_getInstanceMethod([NSMutableOrderedSet class], @selector(setObject:atIndexedSubscript:))) { 
     sprintf(types, "[email protected]:@%s", @encode(NSUInteger)); 
     class_addMethod([NSMutableOrderedSet class], 
         @selector(setObject:atIndexedSubscript:), 
         (IMP)PatchedSetObjectAtIndexedSubscript, 
         types); 
    } 
} 

在你的應用程序的啓動(-application:didFinishLaunchingWithOptions:也許)調用SIPatchNSOrderedSet()

+0

WOW。只是哇。所以我們不能只是做正常的類別,我們可以嗎? –

+0

v @:@%s爲什麼不是v @:@ s?爲什麼%s之前?這裏沒有列出https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html#//apple_ref/doc/uid/TP40008048-CH100 –

+0

@JimThio這不是一個正常的因爲我不想覆蓋iOS 6中的實際實現,所以當條件不可用時,我有條件地覆蓋它。 –

3

在尋找到這一點更深,它看起來像它NSOrderSet只有-objectAtIndexedSubscript:在iOS 6,但NSArray在iOS 5和iOS 6中都有-objectAtIndexedSubscript:

我的測試顯示如下。

- (void)testNSOrderedSetObjectAtIndexedSubscript 
{ 
    NSString *systemVersion = [UIDevice currentDevice].systemVersion; 
    NSString *message = @"NSOrderedSet for %@ does not respond to -objectAtIndexedSubscript:"; 

    NSOrderedSet *orderedSet = [NSOrderedSet orderedSet]; 
    STAssertTrue([orderedSet respondsToSelector:@selector(objectAtIndexedSubscript:)], message, systemVersion); 
} 

- (void)testNSArrayObjectAtIndexedSubscript 
{ 
    NSString *systemVersion = [UIDevice currentDevice].systemVersion; 
    NSString *message = @"NSArray for %@ does not respond to -objectAtIndexedSubscript:"; 

    NSArray *array = [NSArray array]; 
    STAssertTrue([array respondsToSelector:@selector(objectAtIndexedSubscript:)], message, systemVersion); 
} 

的iOS 5.0模擬器

Test Case '-[SIObjectTests testNSArrayObjectAtIndexedSubscript]' started. 
Test Case '-[SIObjectTests testNSArrayObjectAtIndexedSubscript]' passed (0.000 seconds). 
Test Case '-[SIObjectTests testNSOrderedSetObjectAtIndexedSubscript]' started. 
/Users/jthomas/workspaces/si-catalog-order-ios/SICatalogOrderTests/SIObjectTests.m:20: error: -[SIObjectTests testNSOrderedSetObjectAtIndexedSubscript] : "[orderedSet respondsToSelector:@selector(objectAtIndexedSubscript:)]" should be true. NSOrderedSet for 5.0 does not respond to -objectAtIndexedSubscript: 
Test Case '-[SIObjectTests testNSOrderedSetObjectAtIndexedSubscript]' failed (0.000 seconds). 

的iOS 6.0模擬器

Test Case '-[SIObjectTests testNSArrayObjectAtIndexedSubscript]' started. 
Test Case '-[SIObjectTests testNSArrayObjectAtIndexedSubscript]' passed (0.000 seconds). 
Test Case '-[SIObjectTests testNSOrderedSetObjectAtIndexedSubscript]' started. 
Test Case '-[SIObjectTests testNSOrderedSetObjectAtIndexedSubscript]' passed (0.000 seconds). 
+0

什麼是stassert是真的,那和其他人有什麼區別? –

+0

@JimThio'STAssert *'函數是OCUnit的一部分。 –

+0

爲什麼不使用普通的NSAssert? –

0

Jeffry的回答非常好,並提供了有關如何聲明選擇器工作的信息。

對於替代方案,我只是這樣做:

self.businessDetailed.Phones.array[0]; 

然後我會告訴我未來的孫子改變,要

self.businessDetailed.Phones[0]; 

當iPhone 15擊中貨架。

比Jeffry的解決方案少得多的工作,但邊際成本略有增加。

相關問題