Home Php C# Sql C C++ Javascript Python Java Go Android Git Linux Asp.net Django .net Node.js Ios Xcode Cocoa Iphone Mysql Tomcat Mongodb Bash Objective-c Scala Visual-studio Apache Elasticsearch Jar Eclipse Jquery Ruby-on-rails Ruby Rubygems Android-studio Spring Lua Sqlite Emacs Ubuntu Perl Docker Swift Amazon-web-services Svn Html Ajax Xml Java-ee Maven Intellij-idea Rvm Macos Unix Css Ipad Postgresql Css3 Json Windows-server Vue.js Typescript Oracle Hibernate Internet-explorer Github Tensorflow Laravel Symfony Redis Html5 Google-app-engine Nginx Firefox Sqlalchemy Lucene Erlang Flask Vim Solr Webview Facebook Zend-framework Virtualenv Nosql Ide Twitter Safari Flutter Bundle Phonegap Centos Sphinx Actionscript Tornado Register | Login | Edit Tags | New Questions | 繁体 | 简体


10 questions online user: 2

0
votes
answers
51 views
+10

通過檢查像SKStoreProductParameterAffiliateToken這樣的常量的地址來完成什麼?

3

我從我正在使用的庫中獲取該代碼。通過檢查像SKStoreProductParameterAffiliateToken這樣的常量的地址來完成什麼?

#ifdef __IPHONE_8_0 
    if (&SKStoreProductParameterAffiliateToken) { 
     if (self.affiliateToken) { 
      [appParameters setObject:self.affiliateToken forKey:SKStoreProductParameterAffiliateToken]; 
      if (self.campaignToken) { 
       [appParameters setObject:self.campaignToken forKey:SKStoreProductParameterCampaignToken]; 
      } 
     } 
    } 
#endif 

Xcode是說第一行總是會被評估爲true,但是這條線究竟是做什麼的?我從來沒有看到一個if&,並以這種方式常數。

SKStoreProductParameterAffiliateToken被定義爲

SK_EXTERN NSString * const SKStoreProductParameterAffiliateToken NS_AVAILABLE_IOS(8_0); 

什麼是開發嘗試檢查,恆定的地址?他是否試圖檢查iOS的版本是否具有此常量定義,並且通過這樣做,他試圖檢查if中是否應該運行?但他已經有ifdef __IPHONE_8_0 ...(?? !!)

我不明白這一點。

無論如何,我正在編譯的iOS 9.3,所以我可以刪除ififdef,對不對?

+0

至少運行'SKStoreProductParameterAffiliateToken'在IOS 8.0加入。如果你不需要支持iOS 7,那麼你可以刪除'#ifdef'和'if'。 – rmaddy

沙发
0
3

這是一個檢查,看是否有弱鏈接符號是可用的。如果包含該符號的庫/框架已被弱連接並且不可用,則其地址將評估爲NULL並且if條件將是錯誤的。

請參閱使用Apple的Using SDK-Based Development中的弱連接方法,函數和符號瞭解完整詳細信息。

板凳
0
0

#ifdef __IPHONE_8_0檢查的Xcode裏面應該編譯代碼。較舊版本的Xcode將顯示有關未知變量SKStoreProductParameterAffiliateToken的錯誤。

但是,使用新版本的Xcode(與iOS SDK 8+)的時候,我們可能仍然可以爲我們的項目設置一個較低的最低目標。在這種情況下,爲了避免iOS8以下版本的設備發生崩潰,我們應該首先檢查是否存在變量,類,方法或函數。

在你的情況,我們正在檢查,如果指針SKStoreProductParameterAffiliateTokenNULL,這意味着應用程序是目前在iOS 8

0
votes
answers
93 views
+10

在ios中切換任務時發生虛假旋轉事件11

2

當您在iPad上使用4指任務切換手勢切換時,我的應用程序在返回時崩潰。在ios中切換任務時發生虛假旋轉事件11

當用戶執行了4指手勢,從我的應用程序中切換出來,我在我的應用程序委託看到applicationWillResignActive:然後applicationDidEnterBackground:,然後(假設我們目前正處在縱向)我頂層視圖控制器獲取viewWillTransitionToSize:withTransitionCoordinator:與表示橫向佈局的大小(即使設備未旋轉)。這當然會導致很多調整和重新安排新方向的觀點。緊接着,我得到viewWillTransitionToSize:withTransitionCoordinator:,其大小指示肖像(設備的原始方向)。再次,我再次爲新的(實際上是原創的)方向進行我的佈局。

我在找的是如果我等待所有這些完成,我可以全天進入和退出我的應用程序。另一方面,如果在這個不必要的工作正在進行時切換回我的應用程序,我會在某些iOS轉換代碼中發生崩潰。

在這一點上,我試圖理解爲什麼我會得到這些流浪的旋轉事件。如果我能避免這些事情發生,我可以避免陷入任何導致事故發生的情況。他們似乎並不必要。

+1

感謝您指出這一點。起初我以爲我無法複製它,然後我意識到,我不僅可以重現它,而且事實上我的應用程序在App Store上充滿了崩潰報告! – matt

+0

我發現了另一種情況發生這種情況,當用戶在應用處於多任務狀態時單擊主頁按鈕時。當應用程序處於後臺狀態時,再次連續兩次「viewWillTransitionToSize」。 – matt

+0

我在想它這樣做的原因是它可以在橫向和縱向上快照應用程序,以便它可以在其正在運行的應用程序列表中顯示縮略圖。使用適當的代碼繞過後臺發生的方向更改,將橫向退出應用程序,旋轉至縱向,然後雙擊主屏幕以顯示正在運行的應用程序。你的屏幕截圖是錯誤的。我認爲要真正解決這個問題,我需要弄清楚我的旋轉/佈局代碼中觸發iOS中與重疊動畫相關的錯誤。與此同時,我推遲了佈局,直到我的應用程序變爲活動狀態。 – Craig

沙发
0
0

事實證明,沒有辦法阻止嚮應用程序報告輪換事件。我懷疑這是一個iOS錯誤。但是,在應用程序狀態爲UIApplicationStateBackground時忽略viewWillTransitionToSize:withTransitionCoordinator:,並在視圖的layoutSubviews(如果存在)中執行相同操作可以解決此問題。

板凳
0
1

我想不出有任何理由爲什麼它會是有用的或正確獲得viewWillTransitionToSize在後臺,所以只是反彈,如果你背景是

if UIApplication.shared.applicationState == .background { 
    return 
} 

不過,這種感覺就像一個錯誤,在我看來你應該向Apple報告。

+0

換句話說:如果你實現'layoutSubviews',它是否被調用與你是否實現'viewWillTransitionToSize'無關。但是,這不是你所要求的。 – matt

+0

我們是否應該刪除我們的評論?它會更乾淨。 – matt

+0

就像我建議的那樣,刪除所有評論。你的回答站立。評論是短暫的;我們用它們來討論如何進行。現在辯論結束了。 – matt

0
votes
answers
39 views
+10

繪畫時顏色不一致

0

我有一個UIImageView,並使用UIColor orangeColor繪製它。現在,我有一個功能,應該檢測點擊像素的pixelColor。繪畫時顏色不一致

R:1.000000 G:0.501961 B:0.000000

這是RGB值試圖檢測的pixelColor爲UIOrange

它應該是當我收到。

R:1.000000 G:0.5 B:0.000000

這裏是我的功能

- (UIColor *)colorAtPixel:(CGPoint)point { 
    // Cancel if point is outside image coordinates 
    if (!CGRectContainsPoint(CGRectMake(0.0f, 0.0f, _overlay_imageView.frame.size.width, _overlay_imageView.frame.size.height), point)) { 
     return nil; 
    } 


    // Create a 1x1 pixel byte array and bitmap context to draw the pixel into. 
    // Reference: http://stackoverflow.com/questions/1042830/retrieving-a-pixel-alpha-value-for-a-uiimage 
    NSInteger pointX = trunc(point.x); 
    NSInteger pointY = trunc(point.y); 
    CGImageRef cgImage = _overlay_imageView.image.CGImage; 
    NSUInteger width = CGImageGetWidth(cgImage); 
    NSUInteger height = CGImageGetHeight(cgImage); 
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
    int bytesPerPixel = 4; 
    int bytesPerRow = bytesPerPixel * 1; 
    NSUInteger bitsPerComponent = 8; 
    unsigned char pixelData[4] = { 0, 0, 0, 0 }; 
    CGContextRef context = CGBitmapContextCreate(pixelData, 
               1, 
               1, 
               bitsPerComponent, 
               bytesPerRow, 
               colorSpace, 
               kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); 
    CGColorSpaceRelease(colorSpace); 
    CGContextSetBlendMode(context, kCGBlendModeCopy); 

    // Draw the pixel we are interested in onto the bitmap context 
    CGContextTranslateCTM(context, -pointX, -pointY); 
    CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, (CGFloat)width, (CGFloat)height), cgImage); 
    CGContextRelease(context); 

    // Convert color values [0..255] to floats [0.0..1.0] 
    CGFloat red = (CGFloat)pixelData[0]/255.0f; 
    CGFloat green = (CGFloat)pixelData[1]/255.0f; 
    CGFloat blue = (CGFloat)pixelData[2]/255.0f; 
    CGFloat alpha = (CGFloat)pixelData[3]/255.0f; 

    return [UIColor colorWithRed:red green:green blue:blue alpha:alpha]; 
} 

任何想法?

我必須提到,我的UIImageView有一個clearBackground,它的ontop是一個黑色的畫布。這可能是問題嗎?

+0

我不知道你在這裏要求什麼類型的幫助。你可以更具體地瞭解這是一個問題嗎? –

+0

是的,我需要比較顏色值與UIColor colornameColor來查看我是否匹配正確的像素。 – digit

沙发
0
1

你的功能沒有問題。這是浮點數學的結果。整數255(無符號字節的最大值)中的一半是127/255.0或128/255.0,具體取決於您如何舍入。這兩者都不是0.5。他們分別是0.498039215686275和0.501960784313725。

編輯:我想我應該補充一點,在CGImage中的顏色存儲爲字節,而不是浮動。所以當你用UIColor中的float創建橙色時,它會被截斷爲R:255,G:128,B:0 A:255。當你讀回來作爲浮點數得到1.0 0.501961乙:0.0答:1.0

+0

因爲很多主要和次要的顏色是由兩個因子構建的,所以使用256.0作爲常量分母會更好嗎? –

+0

否; 255是UInt8的正確最大值。如果你真的關心四捨五入,那麼只需以字節爲單位指定所有顏色,並且不會有任何轉換或精度損失。如果您在顯示屏P3上使用寬色,則只需要浮點數。 –

+0

Josh Homann:你能否更新我的函數來處理字節,這樣我就可以看到了? – digit

0
votes
answers
49 views
+10

按字母順序對字典進行排序

0

我有3個對象的數組。這些對象屬於字典類型。每個字典都有不同的密鑰。我想按字母順序對這個數組進行排序。按字母順序對字典進行排序

我的數組結構如下

MyListArray:({Return=something;},{Departure=something;},{Both=something;}); 

我如何按字母順序排序呢?

+0

你要像輸出: - 'MyListArray:({=兩個東西;},{ 出發=東西;},{回報=東西;});'??? –

+0

是的。那是我的預期輸出 –

+0

[Objective-C:基於字典條目對NSDictionary的鍵進行排序]的可能重複(https://stackoverflow.com/questions/11554780/objective-c-sort-keys-of-nsdictionary-基於字典條目) –

沙发
0
1

使用sortedArrayUsingComparator:並比較比較器中的鍵。關鍵是字典allKeys中的第一個關鍵字。

NSArray *sortedArray = [myListArray sortedArrayUsingComparator:^(NSDictionary* _Nonnull obj1, NSDictionary* _Nonnull obj2) { 
    if (obj1.count == 0) { 
     if (obj2.count == 0) 
      return NSOrderedSame; 
     else 
      return NSOrderedAscending; 
    } 
    if (obj2.count == 0) 
     return NSOrderedDescending; 
    NSString *key1 = obj1.allKeys[0]; 
    NSString *key2 = obj2.allKeys[0]; 
    return [key1 compare:key2]; 
}]; 
0
votes
answers
70 views
+10

因爲內存增加,iPad在某些時候會崩潰

-3

我正在爲ipad和iphone開發一個項目,這是一個非常老的項目。 我的iPad崩潰在一個主要功能,在這一點上的內存將達到1.6 GB。 但在iphone它正在working.please幫助我解決這個問題。 謝謝soo。因爲內存增加,iPad在某些時候會崩潰

+0

能否請您提供更多詳細信息 –

+0

其實我在昨天之前創建了新的版本,如果我使用iphone運行該版本,它的工作是完美的。 – srinivasreddy

+0

但是,當涉及到iPad,當我運行時,它崩潰了。但我不明白爲什麼。還有一件事是舊版本正常工作,當我將最近的類複製到舊版本,然後老版本alaso崩潰 – srinivasreddy

沙发
0
1

對於我們來說,如果您關心爲我們提供有關您的硬件和您正在處理的特定問題的更多詳細信息,那將會更有幫助。但總的來說,它似乎是一個設計缺陷由於缺乏足夠的內存大部分觀察到Ipad Airs

一般來說,在處理64位環境時,內存佔用量會增加20-30%。隨着更多的應用程序打開,包括一些在後臺進行工作,您可能會看到從內存中相當積極地驅逐應用程序。 儘管iOS版本看起來有所改善,但OS的64位版本似乎仍然比32位版本更頻繁地遇到穩定性問題。這可能只是因爲向64位應用程序(以及相關內存壓力)的轉移給iOS的內存管理例程帶來了更多壓力,這反過來又暴露了一些弱點。

上面的鏈接可能會爲你做的伎倆。祝你好運。

+0

感謝您的回覆。但我的iPad Air擁有22.4 GB可用內存。並且我只在iPhone中運行iPhone Build – srinivasreddy

0
votes
answers
53 views
+10

IB_DESIGNABLE和IBINSTECTABLE UIImageView

0

我想添加一個自定義屬性到我的UIImageView的子類。屬性類型是UIImageView。我已經成功地使用了其他數據類型,UIColor,int等。但是UIImageView並沒有出現在界面構建器的自定義字段中,我無法通過代碼訪問它。IB_DESIGNABLE和IBINSTECTABLE UIImageView

#import <UIKit/UIKit.h> 


IB_DESIGNABLE 
@interface newLayerController : UIImageView 

@property (nonatomic, copy) IBInspectable UIImageView *imageSheet; 

    - (void)drawShape:(CGPoint)point; 
    - (void)endTouch:(CGPoint)point; 
    - (void)startTouch:(CGPoint)point; 

@end 

任何人都知道一個快速修復?

+1

你不能有ibinspectable uiimageview。您可以擁有@property(非原子,複製)IBInspectable UIImage *圖像;您可以在代碼中將其分配給視圖。 –

沙发
0
0

使用UIImage代替UIImageView。

@IBInspectable var backImage: UIImage = UIImage() { 
    didSet{ 
     setbackImage() 
    } 
} 

func setbackImage(){ self.image = backImage} 
0
votes
answers
44 views
+10

「無法識別的選擇」錯誤與橋接報頭,即使它在設置

1

加我加了.H和this project .m文件並創建了一個橋接報。我確信,在橋接報頭位置輸入正確的項目設置...「無法識別的選擇」錯誤與橋接報頭,即使它在設置

Header location in settings

...它導入所需的文件。

header file

我有一個UIView的在我的ViewController其類型設置爲IPDFCameraViewController。在viewDidLoad中()我打電話在這個類的函數:

@IBOutlet weak var cameraViewController: IPDFCameraViewController! 

override func viewDidLoad() { 
    super.viewDidLoad() 

    self.cameraViewController.setupCameraView() 
    self.cameraViewController.isBorderDetectionEnabled = true 

} 

我沒有任何錯誤或警告,但是,當它試圖執行cameraViewController.setupCameraView()崩潰並引發以下:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIView setupCameraView]: unrecognized selector sent to instance 0x7ff1b0930620' 

我米可能錯過了這麼簡單的事情,但這讓我瘋狂,我該怎麼辦?

+0

請包括代碼,不是截圖。還請顯示異常消息的詳細信息。什麼是實例類型和選擇器是什麼?也表明在.H/.m文件 – Paulw11

+0

@ Paulw11我更新的問題是函數的聲明。對於函數聲明,它甚至不在函數中,但是頭部只是' - (void)setupCameraView {}' – cameloper

沙发
0
2

您沒有設置自定義類的故事板視圖,讓您的出口指的UIView一個實例,當然UIView沒有按沒有功能setupCameraView

+0

哇感謝一個重命名,我絕不會想到有關 – cameloper

板凳
0
0

錯誤,因爲你設置類型的UIViewController的UIView。視圖控制器已經被添加爲childViiewControllers不是通過uiviews。在你的故事板添加ContainerViewController,它設置爲您IPDFViewController,然後讓出口

+0

'IPDFCameraViewController'是'UIView'的子類 – cameloper

+0

該類名稱很差。它應該是'IPDFCameraView',因爲它不是視圖控制器。 – Paulw11

+0

是啊,也許我能做到爲 – cameloper

0
votes
answers
31 views
+10

UIView與切出段和陰影

0

我的問題是:我試圖切出自定義UIView段並將陰影效果應用於此視圖。UIView與切出段和陰影

在自定義UIView類,我這樣做:

創建兩層 - 陰影和麪具。添加一個陰影圖層作爲此自定義視圖的子圖層。然後,我創建了一個新視圖,將其蒙版設置爲蒙版圖層,並將其作爲子視圖添加到自定義視圖中。

self.backgroundColor = [UIColor clearColor]; 
CGFloat radius = 40; 
float startAngle = -M_PI; 
float endAngle = 0; 

UIBezierPath *path = [UIBezierPath bezierPathWithRect:self.bounds]; 

[path moveToPoint:CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMaxY(self.bounds)+radius/1.8)]; 
[path addArcWithCenter:CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMaxY(self.bounds)+radius/1.8) radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES]; 

CAShapeLayer *shadowLayer = [[CAShapeLayer alloc] init]; 
shadowLayer.frame = self.bounds; 
shadowLayer.path = path.CGPath; 
shadowLayer.shadowColor = [UIColor grayColor].CGColor; 
shadowLayer.shadowOpacity = 0.5; 
shadowLayer.shadowRadius = 2; 
shadowLayer.masksToBounds = NO; 
shadowLayer.shadowOffset = CGSizeMake(2.0, 2.0); 
shadowLayer.fillRule = kCAFillRuleEvenOdd; 


CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init]; 
maskLayer.frame = self.bounds; 
maskLayer.masksToBounds = NO; 
maskLayer.path = path.CGPath; 
maskLayer.fillRule = kCAFillRuleEvenOdd; 
maskLayer.fillColor = [UIColor whiteColor].CGColor; 

[self.layer addSublayer:shadowLayer]; 

UIView *view = [[UIView alloc] initWithFrame:self.bounds]; 
view.backgroundColor = [UIColor whiteColor]; 
view.layer.mask = maskLayer; 
[self addSubview:view]; 

這就是我想達到什麼 -

enter image description here

,這是我真正得到

enter image description here

如果我設置clipToBounds = YES,將削減關閉所需的陰影效果。

如果我想切割半圓,絕對沒有問題。因爲在這種情況下,半圓形路徑完全位於視圖邊界內。

enter image description here

但我確實需要實現第一個圖像顯示的結果。 我正在考慮逐行建立路徑,但當涉及到這個弧時會出現問題,並且結果可能不會那麼準確。

有沒有人有想法如何可以做? 謝謝!

沙发
0
1

編輯: 如果問題是路徑錯誤,請不要在代碼中使用圓圈和猜測座標來合成路徑。相反,您應該導出座標實際圖稿並使用曲線的圖稿座標。它看起來像你有一個草圖文件,所以最簡單的方法是複製並粘貼到paint code,它會給你曲線的代碼,但如果你沒有繪製代碼??(你應該,它的驚人的這種東西),您可以將草圖中的曲線導出爲SVG。如果您在文本編輯器中打開SVG,您將看到其中的可讀XML文件,您可以從那裏從Bezier曲線中提取控制點。

+0

這就是我實際做的。我創建了兩層 - 陰影和遮罩層。我將陰影圖層添加爲自定義視圖的子圖層。我創建了一個新視圖並將其設置爲遮罩層。它會產生這種奇怪的效果。 – Syngmaster

+0

查看編輯答案。 –

+0

謝謝! PaintCode是一個了不起的工具!它完成了它的工作,現在一切都運行得很完美!唯一的問題是需要調整所有曲線點以在不同的設備尺寸上產生相同的效果。我應該能夠管理:) – Syngmaster

0
votes
answers
46 views
+10

Objective-C改變圖像顏色性能

0

我目前使用下面的函數來改變PNG圖像的顏色,通過顏色滑塊設置顏色,所以當滑動顏色時,一切正常,並得到相應的結果圖像相應地,我是滑動時滑塊的性能只會有問題,它會滯後以及圖像顏色更新,需要幫助才能使過程平滑。Objective-C改變圖像顏色性能

- (UIImage*)imageWithImage:(UIImage *)sourceImage fixedHue:(CGFloat)hue saturation:(CGFloat)saturation brightness:(CGFloat)brightness alpha:(CGFloat)alpha{ 
    CGSize imageSize = [sourceImage size]; 
    UIGraphicsBeginImageContext(imageSize); 
    CGContextRef context = UIGraphicsGetCurrentContext(); 

    CGContextTranslateCTM(context, 0, sourceImage.size.height); 
    CGContextScaleCTM(context, 1.0, -1.0); 

    CGRect rect = CGRectMake(0, 0, sourceImage.size.width, sourceImage.size.height); 

    CGContextSetBlendMode(context, kCGBlendModeNormal); 
    CGContextDrawImage(context, rect, sourceImage.CGImage); 
    CGContextSetBlendMode(context, kCGBlendModeColor); 
    [[UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:alpha] setFill]; 
    CGContextFillRect(context, rect); 
    CGContextSetBlendMode(context, kCGBlendModeDestinationIn); 
    CGContextDrawImage(context, rect, sourceImage.CGImage); 
    CGContextFlush(context); 
    UIImage *editedImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 

    return editedImage; 
} 
沙发
0
0

讓你的函數的異步版本如下...

- (void)imageWithImage:(UIImage *)sourceImage 
       fixedHue:(CGFloat)hue 
      saturation:(CGFloat)saturation 
      brightness:(CGFloat)brightness 
       alpha:(CGFloat)alpha 
      completion:(void (^)(UIImage *))completion { 

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
    dispatch_async(queue, ^{ 
     // call your original function. Use this to create the context... 
     UIGraphicsBeginImageContextWithOptions(imageSize, YES, 0.0); 
     // don't call CGContextFillRect, call... 
     UIRectFill(rect); 
     // don't call CGContextDrawImage, call... 
     [sourceImage drawInRect:rect] 
     // don't call CGContextFlush, don't need to replace that 

     UIImage *image = [self imageWithImage:sourceImage fixedHue:hue saturation:saturation brightness:brightness alpha:alpha]; 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      completion(image); 
     }); 
    }); 
} 

使用方法如下:

- (IBAction)sliderValueChanged:(UISlider *)sender { 
    [self imageWithImage:sourceImage 
       fixedHue:hue 
       saturation:saturation 
       brightness:brightness 
        alpha:alpha 
       completion:^(UIImage *image) { 
        // update the UI here with image 
       }]; 
} 
+0

謝謝DANH,在這條線 CGContextFillRect應用程序崩潰(上下文,rect); 說應該在UI線程上實現,確實在主線程上添加了這條線來調度仍然沒有運氣 – Development

+0

啊 - 對不起。不要獲取當前的上下文。創建一個。將在幾分鐘後發佈修改。 – danh

+0

對不起 - 我只是剛剛仔細閱讀你的原代碼。你創建了一個CGContext,並且我認爲我已經找到了所有需要運行的主要變化(關閉主要的UI操作都是禁止的)。 – danh

0
votes
answers
32 views
+10

EXC_BAD_ACCESS在開始運行應用程序時崩潰?

0

我在我的應用程序中使用linphone SDK。當我開始立即運行應用程序崩潰時。 應用程序啓動後它的呼叫[Fastaddreesbook init]呼籲[FastAddreesBook reload]呼籲[FastAddreesBook loadData]呼籲[FastAddreesBook normalizeSipURI]EXC_BAD_ACCESS在這種方法崩潰發生:EXC_BAD_ACCESS在開始運行應用程序時崩潰?

LinphoneAddress* linphoneAddress = linphone_core_interpret_url([LinphoneManager getLc], [address UTF8String]); 

主題1:EXC_BAD_ACCESS(代碼= 1,地址=爲0x0)

/* FastAddressBook.h 
* 
* Copyright (C) 2011 Belledonne Comunications, Grenoble, France 
* 
* This program is free software; you can redistribute it and/or modify 
* it under the terms of the GNU General Public License as published by 
* the Free Software Foundation; either version 2 of the License, or 
* (at your option) any later version. 
* 
* This program is distributed in the hope that it will be useful, 
* but WITHOUT ANY WARRANTY; without even the implied warranty of 
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
* GNU General Public License for more details. 
* 
* You should have received a copy of the GNU General Public License 
* along with this program; if not, write to the Free Software 
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
*/ 
#ifdef __IPHONE_9_0 
#import <Contacts/Contacts.h> 
#endif 
#import "FastAddressBook.h" 
#import "LinphoneManager.h" 
#import "BundleLocalData.h" 
#import "AppUtil.h" 
#import "WebserviceUtil.h" 
#import "ContactEntry.h" 
#import "ContactsViewController.h" 

@implementation FastAddressBook 

static void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef info, void *context); 

+ (NSString*)getContactDisplayName:(ABRecordRef)contact { 
    NSString *retString = nil; 
    if (contact) { 
     CFStringRef lDisplayName = ABRecordCopyCompositeName(contact); 
     if(lDisplayName != NULL) { 
      retString = [NSString stringWithString:(NSString*)lDisplayName]; 
      CFRelease(lDisplayName); 
     } 
    } 
    return retString; 
} 

+ (UIImage*)squareImageCrop:(UIImage*)image 
{ 
    UIImage *ret = nil; 

    // This calculates the crop area. 

    float originalWidth = image.size.width; 
    float originalHeight = image.size.height; 

    float edge = fminf(originalWidth, originalHeight); 

    float posX = (originalWidth - edge)/2.0f; 
    float posY = (originalHeight - edge)/2.0f; 


    CGRect cropSquare = CGRectMake(posX, posY, 
            edge, edge); 


    CGImageRef imageRef = CGImageCreateWithImageInRect(image.CGImage, cropSquare); 
    ret = [UIImage imageWithCGImage:imageRef 
           scale:image.scale 
         orientation:image.imageOrientation]; 

    CGImageRelease(imageRef); 

    return ret; 
} 

+ (UIImage*)getContactImage:(ABRecordRef)contact thumbnail:(BOOL)thumbnail { 
    UIImage* retImage = nil; 
    if (contact && ABPersonHasImageData(contact)) { 
     CFDataRef imgData = ABPersonCopyImageDataWithFormat(contact, thumbnail? 
                  kABPersonImageFormatThumbnail: kABPersonImageFormatOriginalSize); 

     retImage = [UIImage imageWithData:(NSData *)imgData]; 
     if(imgData != NULL) { 
      CFRelease(imgData); 
     } 

     if (retImage != nil && retImage.size.width != retImage.size.height) { 
      [LinphoneLogger log:LinphoneLoggerLog format:@"Image is not square : cropping it."]; 
      return [self squareImageCrop:retImage]; 
     } 
    } 

    return retImage; 
} 

- (ABRecordRef)getContact:(NSString*)address { 
    @synchronized (addressBookMap){ 
     return (ABRecordRef)addressBookMap[address]; 
    } 
} 

+ (BOOL)isSipURI:(NSString*)address { 
    return [address hasPrefix:@"sip:"] || [address hasPrefix:@"sips:"]; 
} 

+ (NSString*)appendCountryCodeIfPossible:(NSString*)number { 
    if (![number hasPrefix:@"+"] && ![number hasPrefix:@"00"]) { 
     NSString* lCountryCode = [[LinphoneManager instance] lpConfigStringForKey:@"countrycode_preference"]; 
     if (lCountryCode && lCountryCode.length>0) { 
      //append country code 
      return [lCountryCode stringByAppendingString:number]; 
     } 
    } 
    return number; 
} 

+ (NSString*)normalizeSipURI:(NSString*)address { 
    NSString *normalizedSipAddress = nil; 
    LinphoneAddress* linphoneAddress = linphone_core_interpret_url([LinphoneManager getLc], [address UTF8String]); 
    if(linphoneAddress != NULL) { 
     char *tmp = linphone_address_as_string_uri_only(linphoneAddress); 
     if(tmp != NULL) { 
      normalizedSipAddress = [NSString stringWithUTF8String:tmp]; 
      ms_free(tmp); 
     } 
     linphone_address_destroy(linphoneAddress); 
    } 
    return normalizedSipAddress; 
} 

+ (NSString*)normalizePhoneNumber:(NSString*)address { 
    NSMutableString* lNormalizedAddress = [NSMutableString stringWithString:address]; 
    [lNormalizedAddress replaceOccurrencesOfString:@" " 
             withString:@"" 
              options:0 
              range:NSMakeRange(0, lNormalizedAddress.length)]; 
    [lNormalizedAddress replaceOccurrencesOfString:@"(" 
             withString:@"" 
              options:0 
              range:NSMakeRange(0, lNormalizedAddress.length)]; 
    [lNormalizedAddress replaceOccurrencesOfString:@")" 
             withString:@"" 
              options:0 
              range:NSMakeRange(0, lNormalizedAddress.length)]; 
    [lNormalizedAddress replaceOccurrencesOfString:@"-" 
             withString:@"" 
              options:0 
              range:NSMakeRange(0, lNormalizedAddress.length)]; 
    return [FastAddressBook appendCountryCodeIfPossible:lNormalizedAddress]; 
} 

+ (BOOL)isAuthorized { 
    //addme // return !ABAddressBookGetAuthorizationStatus || ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized; 
    return ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized; 
} 


- (FastAddressBook*)init { 
    if ((self = [super init]) != nil) { 
     addressBookMap = [[NSMutableDictionary alloc] init]; 
     addressBook = nil; 
     [self reload]; 
    } 


    self.needToUpdate = FALSE; 
    if ([CNContactStore class]) { 
     //ios9 or later 
     CNEntityType entityType = CNEntityTypeContacts; 
     if([CNContactStore authorizationStatusForEntityType:entityType] == CNAuthorizationStatusNotDetermined) { 
      CNContactStore * contactStore = [[CNContactStore alloc] init]; 
      // nslo(@"CNContactStore requesting authorization"); 
      [contactStore requestAccessForEntityType:entityType completionHandler:^(BOOL granted, NSError * _Nullable error) { 
       //  LOGD(@"CNContactStore authorization granted"); 
      }]; 
     } else if([CNContactStore authorizationStatusForEntityType:entityType]== CNAuthorizationStatusAuthorized) { 
      // LOGD(@"CNContactStore authorization granted"); 
     } 
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateAddressBook:) name:CNContactStoreDidChangeNotification object:nil]; 
    } 


    return self; 
} 




-(void) updateAddressBook:(NSNotification*) notif { 
    // LOGD(@"address book has changed"); 
    self.needToUpdate = TRUE; 
} 




- (void) checkContactListForJogvoiceList { 
    // if (![BundleLocalData isLoadingJogvoiceContactList]) { 
    //  [BundleLocalData setLoadingJogvoiceContactList:true]; 

    int maxPhoneNumberSubmit = 200; 
    NSArray *lContacts = (NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook); 
    NSMutableDictionary *phoneNumberContactsDictionary = [[NSMutableDictionary alloc] init]; 
    NSMutableArray *allPhoneNumberList = [[NSMutableArray alloc] init]; 
    for (id lPerson in lContacts) { 
     ABRecordRef person = (ABRecordRef)lPerson; 
     NSArray *phoneList = [AppUtil getContactPhoneList:person]; 
     for (NSString* phoneNumber in phoneList) { 
      NSMutableArray* contactList = phoneNumberContactsDictionary[phoneNumber]; 
      if (!contactList) { 
       contactList = [[NSMutableArray alloc] init]; 
      } 
      [contactList addObject:(__bridge ABRecordRef)person]; 
      phoneNumberContactsDictionary[phoneNumber] = contactList; 
     } 
     [allPhoneNumberList addObjectsFromArray:phoneList]; 

     if (allPhoneNumberList.count >= maxPhoneNumberSubmit) { 
      [self checkContactList:allPhoneNumberList phoneNumberContactsDictionary:phoneNumberContactsDictionary]; 
     } 
    } 

    if (allPhoneNumberList.count > 0) { 
     [self checkContactList:allPhoneNumberList phoneNumberContactsDictionary:phoneNumberContactsDictionary]; 
    } 


    //  ABAddressBookUnregisterExternalChangeCallback(addressBook, sync_address_book, self); 

    //  [BundleLocalData setLoadingJogvoiceContactList:false]; 
    // } 
} 

-(void) checkContactList:(NSMutableArray*)allPhoneNumberList phoneNumberContactsDictionary:(NSMutableDictionary*)phoneNumberContactsDictionary { 

    [WebserviceUtil apiGetUsersRegistered:[NSArray arrayWithArray:allPhoneNumberList] 
            success:^(AFHTTPRequestOperation *operation, id responseObject){ 

             NSDictionary* response = responseObject; 
             for (id phoneNumber in allPhoneNumberList) { 
              NSNumber *status = response[phoneNumber]; 
              if (status.intValue == 1) { // registered 
               NSArray* contactList = phoneNumberContactsDictionary[phoneNumber]; 
               for (int index = 0; index < contactList.count; index++) { 
                ABRecordRef contact = (__bridge ABRecordRef) contactList[index]; 
                [self saveContact:phoneNumber contact:contact]; 
               } 
              } 
             } 
             [self saveAddressBook]; 
             [allPhoneNumberList removeAllObjects]; 

            } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 
             // nothing 
            }]; 

} 

-(void) saveContact:(NSString*)phoneNumber contact:(ABRecordRef)contact { 

    if(contact == NULL || phoneNumber == NULL) { 
     return; 
    } 

    ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonInstantMessageProperty); 
    if (!lMap) { 
     return; 
    } 
    BOOL avafoneAlready = false; 
    for(int i = 0; i < ABMultiValueGetCount(lMap); ++i) { 
     ABMultiValueIdentifier identifier = ABMultiValueGetIdentifierAtIndex(lMap, i); 
     CFDictionaryRef lDict = ABMultiValueCopyValueAtIndex(lMap, i); 
     if(CFDictionaryContainsKey(lDict, kABPersonInstantMessageServiceKey)) { 
      if(CFStringCompare((CFStringRef)[LinphoneManager instance].contactSipField, CFDictionaryGetValue(lDict, kABPersonInstantMessageServiceKey), kCFCompareCaseInsensitive) == 0) { 
       avafoneAlready = true; 
      } 
     } else { 
      //check domain 
      LinphoneAddress* address = linphone_address_new(((NSString*)CFDictionaryGetValue(lDict,kABPersonInstantMessageUsernameKey)).UTF8String); 
      if (address) { 
       if ([[ContactSelection getSipFilter] compare:@"*" options:NSCaseInsensitiveSearch] == NSOrderedSame) { 
        avafoneAlready = true; 
       } else { 
        NSString* domain = [NSString stringWithCString:linphone_address_get_domain(address) 
                  encoding:[NSString defaultCStringEncoding]]; 
        if ([domain compare:[ContactSelection getSipFilter] options:NSCaseInsensitiveSearch] == NSOrderedSame) { 
         avafoneAlready = true; 
        } 
       } 
       linphone_address_destroy(address); 
      } 
     } 
     CFRelease(lDict); 
     if(avafoneAlready) { 
      avafoneAlready = true; 
      break; 
     } 
    } 
    CFRelease(lMap); 

    if (avafoneAlready) { 
     return; 
    } 
    NSString *value = [NSString stringWithFormat:@"900%@", phoneNumber]; 
    ContactEntry *entry = nil; 

    ABMultiValueRef lcMap = ABRecordCopyValue(contact, kABPersonInstantMessageProperty); 
    if(lcMap != NULL) { 
     lMap = ABMultiValueCreateMutableCopy(lcMap); 
     CFRelease(lcMap); 
    } else { 
     lMap = ABMultiValueCreateMutable(kABStringPropertyType); 
    } 
    ABMultiValueIdentifier index; 
    NSError* error = NULL; 

    CFStringRef keys[] = { kABPersonInstantMessageUsernameKey, kABPersonInstantMessageServiceKey}; 
    CFTypeRef values[] = { [value copy], [LinphoneManager instance].contactSipField }; 
    CFDictionaryRef lDict = CFDictionaryCreate(NULL, (const void **)&keys, (const void **)&values, 2, NULL, NULL); 
    if (entry) { 
     index = ABMultiValueGetIndexForIdentifier(lMap, entry.identifier); 
     ABMultiValueReplaceValueAtIndex(lMap, lDict, index); 
    } else { 
     CFStringRef label = (CFStringRef)[NSString stringWithString:(NSString*)kABPersonPhoneMobileLabel]; 
     ABMultiValueAddValueAndLabel(lMap, lDict, label, &index); 
    } 

    if (!ABRecordSetValue(contact, kABPersonInstantMessageProperty, lMap, (CFErrorRef*)&error)) { 
     [LinphoneLogger log:LinphoneLoggerLog format:@"Can't set contact with value [%@] cause [%@]", value,error.localizedDescription]; 
     CFRelease(lMap); 
    } else { 
     if (entry == nil) { 
      entry = [[[ContactEntry alloc] initWithData:index] autorelease]; 
     } 
     CFRelease(lDict); 
     CFRelease(lMap); 

     /*check if message type is kept or not*/ 
     lcMap = ABRecordCopyValue(contact, kABPersonInstantMessageProperty); 
     lMap = ABMultiValueCreateMutableCopy(lcMap); 
     CFRelease(lcMap); 
     index = ABMultiValueGetIndexForIdentifier(lMap, entry.identifier); 
     lDict = ABMultiValueCopyValueAtIndex(lMap,index); 
     //  if(!CFDictionaryContainsKey(lDict, kABPersonInstantMessageServiceKey)) { 
     /*too bad probably a gtalk number, storing uri*/ 
     NSString* username = CFDictionaryGetValue(lDict, kABPersonInstantMessageUsernameKey); 
     LinphoneAddress* address = linphone_core_interpret_url([LinphoneManager getLc] 
                   ,username.UTF8String); 
     if(address){ 
      char* uri = linphone_address_as_string_uri_only(address); 
      CFStringRef keys[] = { kABPersonInstantMessageUsernameKey, kABPersonInstantMessageServiceKey}; 
      CFTypeRef values[] = { [NSString stringWithCString:uri encoding:[NSString defaultCStringEncoding]], [LinphoneManager instance].contactSipField }; 
      CFDictionaryRef lDict2 = CFDictionaryCreate(NULL, (const void **)&keys, (const void **)&values, 2, NULL, NULL); 
      ABMultiValueReplaceValueAtIndex(lMap, lDict2, index); 
      if (!ABRecordSetValue(contact, kABPersonInstantMessageProperty, lMap, (CFErrorRef*)&error)) { 
       [LinphoneLogger log:LinphoneLoggerLog format:@"Can't set contact with value [%@] cause [%@]", value,error.localizedDescription]; 
      } 
      CFRelease(lDict2); 
      linphone_address_destroy(address); 
      ms_free(uri); 
     } 
     //  } 
     CFDictionaryRef lDict = CFDictionaryCreate(NULL, (const void **)&keys, (const void **)&values, 2, NULL, NULL); 
     ABMultiValueReplaceValueAtIndex(lMap, lDict, index); 
     CFRelease(lMap); 
    } 
    CFRelease(lDict); 



} 

- (void)saveAddressBook { 
    if(addressBook != nil){ 
     NSError* err = nil; 
     if(!ABAddressBookSave(addressBook, (CFErrorRef*)err)){ 
      Linphone_warn(@"Couldn't save Address Book"); 
     } 
    } 
} 

- (void)reload { 
    NSLog(@"Fastadd reload first is loaded"); 


    CFErrorRef error; 

    // create if it doesn't exist 
    if (addressBook == nil) { 
    addressBook = ABAddressBookCreateWithOptions(NULL, &error); 
    } 

    if (addressBook != nil) { 
    __weak FastAddressBook *weakSelf = self; 
    ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) { 
    if (!granted) { 
    Linphone_warn(@"Permission for address book acces was denied: %@", [(__bridge NSError *)error description]); 
    return; 
    } 

    ABAddressBookRegisterExternalChangeCallback(addressBook, sync_address_book, (__bridge void *)(weakSelf)); 
    dispatch_async(dispatch_get_main_queue(), ^(void) { 
    [weakSelf loadData]; 
    }); 

    }); 
    } else { 
    Linphone_warn(@"Create AddressBook failed, reason: %@", [(__bridge NSError *)error localizedDescription]); 
    } 




    /* 
    //method1 

    if(addressBook != nil) { 
    ABAddressBookUnregisterExternalChangeCallback(addressBook, sync_address_book, self); 
    CFRelease(addressBook); 
    addressBook = nil; 
    } 
    NSError *error = nil; 

    addressBook = ABAddressBookCreateWithOptions(NULL, NULL); 
    if(addressBook != NULL) { 
    ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) { 
    ABAddressBookRegisterExternalChangeCallback (addressBook, sync_address_book, self); 
    [self loadData]; 
    }); 
    } else { 
    [LinphoneLogger log:LinphoneLoggerError format:@"Create AddressBook: Fail(%@)", [error localizedDescription]]; 
    } 

    */ 



    } 






- (void)loadData { 
    ABAddressBookRevert(addressBook); 
    @synchronized (addressBookMap) { 
     [addressBookMap removeAllObjects]; 
     //melog 
     NSLog(@"Fastadd loaddata is loaded"); 
     NSArray *lContacts = (NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook); 
     for (id lPerson in lContacts) { 
      // Phone 
      { 
       ABMultiValueRef lMap = ABRecordCopyValue((ABRecordRef)lPerson, kABPersonPhoneProperty); 
       if(lMap) { 
        for (int i=0; i<ABMultiValueGetCount(lMap); i++) { 
         CFStringRef lValue = ABMultiValueCopyValueAtIndex(lMap, i); 
         CFStringRef lLabel = ABMultiValueCopyLabelAtIndex(lMap, i); 
         CFStringRef lLocalizedLabel = ABAddressBookCopyLocalizedLabel(lLabel); 
         NSString* lNormalizedKey = [FastAddressBook normalizePhoneNumber:(NSString*)lValue]; 
         NSString* lNormalizedSipKey = [FastAddressBook normalizeSipURI:lNormalizedKey]; 
         if (lNormalizedSipKey != NULL) lNormalizedKey = lNormalizedSipKey; 
         addressBookMap[lNormalizedKey] = lPerson; 
         CFRelease(lValue); 
         if (lLabel) CFRelease(lLabel); 
         if (lLocalizedLabel) CFRelease(lLocalizedLabel); 
        } 
        CFRelease(lMap); 
       } 
      } 

      // SIP 
      { 
       ABMultiValueRef lMap = ABRecordCopyValue((ABRecordRef)lPerson, kABPersonInstantMessageProperty); 
       if(lMap) { 
        for(int i = 0; i < ABMultiValueGetCount(lMap); ++i) { 
         CFDictionaryRef lDict = ABMultiValueCopyValueAtIndex(lMap, i); 
         BOOL add = false; 
         if(CFDictionaryContainsKey(lDict, kABPersonInstantMessageServiceKey)) { 
          CFStringRef contactSipField = (CFStringRef)[LinphoneManager instance].contactSipField; 
          if (!contactSipField) { 
           contactSipField = CFStringCreateWithCString(NULL, "SIP", kCFStringEncodingMacRoman); 
          } 
          if(CFStringCompare(contactSipField, CFDictionaryGetValue(lDict, kABPersonInstantMessageServiceKey), kCFCompareCaseInsensitive) == 0) { 
           add = true; 
          } 
         } else { 
          add = true; 
         } 
         if(add) { 

          CFStringRef lValue = CFDictionaryGetValue(lDict, kABPersonInstantMessageUsernameKey); 
          NSString* lNormalizedKey = [FastAddressBook normalizeSipURI:(NSString*)lValue]; 
          if(lNormalizedKey != NULL) { 
           addressBookMap[lNormalizedKey] = lPerson; 
          } else { 
           addressBookMap[(NSString*)lValue] = lPerson; 
          } 


          /* 
          NSString *lValue = 
          (__bridge NSString *)CFDictionaryGetValue(lDict, kABPersonInstantMessageUsernameKey); 
          NSString *lNormalizedKey = [FastAddressBook normalizeSipURI:lValue]; 
          if (lNormalizedKey != NULL) { 
           [addressBookMap setObject:(__bridge id)(lPerson)forKey:lNormalizedKey]; 
          } else { 
           [addressBookMap setObject:(__bridge id)(lPerson)forKey:lValue]; 
          } 

          */ 
         } 
         CFRelease(lDict); 
        } 
        CFRelease(lMap); 
       } 
      } 
     } 
     CFRelease(lContacts); 
    } 
    [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneAddressBookUpdate object:self]; 
} 


void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef info, void *context) { 
    FastAddressBook* fastAddressBook = (FastAddressBook*)context; 
    [fastAddressBook loadData]; 
} 

- (void)dealloc { 
    ABAddressBookUnregisterExternalChangeCallback(addressBook, sync_address_book, self); 
    CFRelease(addressBook); 
    [addressBookMap release]; 
    [super dealloc]; 
} 

@end 

PS:

-i使用非弧形p roject

-zombie啓用也沒有改變。

- 值是會和那是因爲崩潰發生。

調試控制檯: 警告:無法執行支持代碼來讀取進程中的Objective-C類數據。這可能會降低可用類型信息的質量。

enter image description hereenter image description here

+2

這是基本調試我的朋友。你正試圖訪問一個0指針。查看代碼,看看它爲什麼是0並修復它。 –

沙发
0
0
LinphoneAddress* linphoneAddress = linphone_core_interpret_url([LinphoneManager getLc], [address UTF8String]); 

address爲零。弄清楚爲什麼是這樣,你已經得到了你的崩潰源。它可能應該是零,因爲它可能是原始記錄中的可選字段。

這段代碼有點亂,順便說一句。它不遵循標準模式(例如,以get爲前綴的許多方法)。它確實應該現代化,並啓用ARC。

+0

(IValue爲零,但IDict有價值。)此行返回零,但我不知道爲什麼? CFStringRef lValue = CFDictionaryGetValue(lDict,kABPersonInstantMessageUsernameKey); –

+0

因爲該鍵沒有值。用戶沒有即時消息用戶名。 – bbum

+0

爲什麼代碼在模擬器中可以正常工作,但不能在真實的device.Mybe它有內存問題。 –